Make moving Shapes, swapping Textures and swapping VertexBuffers noexcept.
This commit is contained in:
parent
66bec29aff
commit
f4e0c4b4c0
@ -46,12 +46,6 @@ class Texture;
|
|||||||
class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
|
class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Virtual destructor
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
~Shape() override;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Change the source texture of the shape
|
/// \brief Change the source texture of the shape
|
||||||
///
|
///
|
||||||
|
@ -518,7 +518,7 @@ public:
|
|||||||
/// \param right Instance to swap with
|
/// \param right Instance to swap with
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void swap(Texture& right);
|
void swap(Texture& right) noexcept;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the underlying OpenGL handle of the texture.
|
/// \brief Get the underlying OpenGL handle of the texture.
|
||||||
@ -621,6 +621,15 @@ private:
|
|||||||
std::uint64_t m_cacheId; //!< Unique number that identifies the texture to the render target's cache
|
std::uint64_t m_cacheId; //!< Unique number that identifies the texture to the render target's cache
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Swap the contents of one texture with those of another
|
||||||
|
///
|
||||||
|
/// \param left First instance to swap
|
||||||
|
/// \param right Second instance to swap
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void swap(Texture& left, Texture& right) noexcept;
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ public:
|
|||||||
/// \param right Instance to swap with
|
/// \param right Instance to swap with
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void swap(VertexBuffer& right);
|
void swap(VertexBuffer& right) noexcept;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the underlying OpenGL handle of the vertex buffer.
|
/// \brief Get the underlying OpenGL handle of the vertex buffer.
|
||||||
@ -338,6 +338,15 @@ private:
|
|||||||
Usage m_usage{Stream}; //!< How this vertex buffer is to be used
|
Usage m_usage{Stream}; //!< How this vertex buffer is to be used
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Swap the contents of one vertex buffer with those of another
|
||||||
|
///
|
||||||
|
/// \param left First instance to swap
|
||||||
|
/// \param right Second instance to swap
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void swap(VertexBuffer& left, VertexBuffer& right) noexcept;
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,6 +126,17 @@ endif()
|
|||||||
sfml_find_package(Freetype INCLUDE "FREETYPE_INCLUDE_DIRS" LINK "FREETYPE_LIBRARY")
|
sfml_find_package(Freetype INCLUDE "FREETYPE_INCLUDE_DIRS" LINK "FREETYPE_LIBRARY")
|
||||||
target_link_libraries(sfml-graphics PRIVATE Freetype)
|
target_link_libraries(sfml-graphics PRIVATE Freetype)
|
||||||
|
|
||||||
|
# on some platforms (e.g. Raspberry Pi 3 armhf), GCC requires linking libatomic to use <atomic> features
|
||||||
|
# that aren't supported by native CPU instructions (64-bit atomic operations on 32-bit architecture)
|
||||||
|
if(SFML_COMPILER_GCC)
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
check_cxx_source_compiles("#include <atomic>
|
||||||
|
int main(){std::atomic_ullong x(1); return x.fetch_add(1);}" ATOMIC_TEST)
|
||||||
|
if(NOT ATOMIC_TEST)
|
||||||
|
target_link_libraries(sfml-graphics PRIVATE atomic)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# add preprocessor symbols
|
# add preprocessor symbols
|
||||||
target_compile_definitions(sfml-graphics PRIVATE "STBI_FAILURE_USERMSG")
|
target_compile_definitions(sfml-graphics PRIVATE "STBI_FAILURE_USERMSG")
|
||||||
|
|
||||||
|
@ -48,10 +48,6 @@ sf::Vector2f computeNormal(const sf::Vector2f& p1, const sf::Vector2f& p2)
|
|||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Shape::~Shape() = default;
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void Shape::setTexture(const Texture* texture, bool resetRect)
|
void Shape::setTexture(const Texture* texture, bool resetRect)
|
||||||
{
|
{
|
||||||
|
@ -33,10 +33,10 @@
|
|||||||
#include <SFML/Window/Context.hpp>
|
#include <SFML/Window/Context.hpp>
|
||||||
#include <SFML/Window/Window.hpp>
|
#include <SFML/Window/Window.hpp>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <mutex>
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
|
||||||
@ -45,18 +45,13 @@ namespace
|
|||||||
// A nested named namespace is used here to allow unity builds of SFML.
|
// A nested named namespace is used here to allow unity builds of SFML.
|
||||||
namespace TextureImpl
|
namespace TextureImpl
|
||||||
{
|
{
|
||||||
std::recursive_mutex idMutex;
|
|
||||||
std::recursive_mutex maximumSizeMutex;
|
|
||||||
|
|
||||||
// Thread-safe unique identifier generator,
|
// Thread-safe unique identifier generator,
|
||||||
// is used for states cache (see RenderTarget)
|
// is used for states cache (see RenderTarget)
|
||||||
std::uint64_t getUniqueId()
|
std::uint64_t getUniqueId() noexcept
|
||||||
{
|
{
|
||||||
std::lock_guard lock(idMutex);
|
static std::atomic<std::uint64_t> id(1); // start at 1, zero is "no texture"
|
||||||
|
|
||||||
static std::uint64_t id = 1; // start at 1, zero is "no texture"
|
return id.fetch_add(1);
|
||||||
|
|
||||||
return id++;
|
|
||||||
}
|
}
|
||||||
} // namespace TextureImpl
|
} // namespace TextureImpl
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -832,21 +827,18 @@ void Texture::bind(const Texture* texture, CoordinateType coordinateType)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
unsigned int Texture::getMaximumSize()
|
unsigned int Texture::getMaximumSize()
|
||||||
{
|
{
|
||||||
std::lock_guard lock(TextureImpl::maximumSizeMutex);
|
static const unsigned int size = []()
|
||||||
|
|
||||||
static bool checked = false;
|
|
||||||
static GLint size = 0;
|
|
||||||
|
|
||||||
if (!checked)
|
|
||||||
{
|
{
|
||||||
checked = true;
|
|
||||||
|
|
||||||
TransientContextLock transientLock;
|
TransientContextLock transientLock;
|
||||||
|
|
||||||
glCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size));
|
GLint value = 0;
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<unsigned int>(size);
|
glCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value));
|
||||||
|
|
||||||
|
return static_cast<unsigned int>(value);
|
||||||
|
}();
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -862,7 +854,7 @@ Texture& Texture::operator=(const Texture& right)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void Texture::swap(Texture& right)
|
void Texture::swap(Texture& right) noexcept
|
||||||
{
|
{
|
||||||
std::swap(m_size, right.m_size);
|
std::swap(m_size, right.m_size);
|
||||||
std::swap(m_actualSize, right.m_actualSize);
|
std::swap(m_actualSize, right.m_actualSize);
|
||||||
@ -905,4 +897,11 @@ unsigned int Texture::getValidSize(unsigned int size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void swap(Texture& left, Texture& right) noexcept
|
||||||
|
{
|
||||||
|
left.swap(right);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <mutex>
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@ -42,8 +41,6 @@ namespace
|
|||||||
// A nested named namespace is used here to allow unity builds of SFML.
|
// A nested named namespace is used here to allow unity builds of SFML.
|
||||||
namespace VertexBufferImpl
|
namespace VertexBufferImpl
|
||||||
{
|
{
|
||||||
std::recursive_mutex isAvailableMutex;
|
|
||||||
|
|
||||||
GLenum usageToGlEnum(sf::VertexBuffer::Usage usage)
|
GLenum usageToGlEnum(sf::VertexBuffer::Usage usage)
|
||||||
{
|
{
|
||||||
switch (usage)
|
switch (usage)
|
||||||
@ -274,7 +271,7 @@ VertexBuffer& VertexBuffer::operator=(const VertexBuffer& right)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void VertexBuffer::swap(VertexBuffer& right)
|
void VertexBuffer::swap(VertexBuffer& right) noexcept
|
||||||
{
|
{
|
||||||
std::swap(m_size, right.m_size);
|
std::swap(m_size, right.m_size);
|
||||||
std::swap(m_buffer, right.m_buffer);
|
std::swap(m_buffer, right.m_buffer);
|
||||||
@ -333,22 +330,15 @@ VertexBuffer::Usage VertexBuffer::getUsage() const
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool VertexBuffer::isAvailable()
|
bool VertexBuffer::isAvailable()
|
||||||
{
|
{
|
||||||
std::lock_guard lock(VertexBufferImpl::isAvailableMutex);
|
static const bool available = []() -> bool
|
||||||
|
|
||||||
static bool checked = false;
|
|
||||||
static bool available = false;
|
|
||||||
|
|
||||||
if (!checked)
|
|
||||||
{
|
{
|
||||||
checked = true;
|
|
||||||
|
|
||||||
TransientContextLock contextLock;
|
TransientContextLock contextLock;
|
||||||
|
|
||||||
// Make sure that extensions are initialized
|
// Make sure that extensions are initialized
|
||||||
sf::priv::ensureExtensionsInit();
|
sf::priv::ensureExtensionsInit();
|
||||||
|
|
||||||
available = GLEXT_vertex_buffer_object;
|
return GLEXT_vertex_buffer_object;
|
||||||
}
|
}();
|
||||||
|
|
||||||
return available;
|
return available;
|
||||||
}
|
}
|
||||||
@ -361,4 +351,11 @@ void VertexBuffer::draw(RenderTarget& target, const RenderStates& states) const
|
|||||||
target.draw(*this, 0, m_size, states);
|
target.draw(*this, 0, m_size, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void swap(VertexBuffer& left, VertexBuffer& right) noexcept
|
||||||
|
{
|
||||||
|
left.swap(right);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
static_assert(std::is_copy_constructible_v<sf::CircleShape>);
|
static_assert(std::is_copy_constructible_v<sf::CircleShape>);
|
||||||
static_assert(std::is_copy_assignable_v<sf::CircleShape>);
|
static_assert(std::is_copy_assignable_v<sf::CircleShape>);
|
||||||
static_assert(std::is_move_constructible_v<sf::CircleShape>);
|
static_assert(std::is_nothrow_move_constructible_v<sf::CircleShape>);
|
||||||
static_assert(std::is_move_assignable_v<sf::CircleShape>);
|
static_assert(std::is_nothrow_move_assignable_v<sf::CircleShape>);
|
||||||
|
|
||||||
TEST_CASE("[Graphics] sf::CircleShape")
|
TEST_CASE("[Graphics] sf::CircleShape")
|
||||||
{
|
{
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
static_assert(std::is_copy_constructible_v<sf::ConvexShape>);
|
static_assert(std::is_copy_constructible_v<sf::ConvexShape>);
|
||||||
static_assert(std::is_copy_assignable_v<sf::ConvexShape>);
|
static_assert(std::is_copy_assignable_v<sf::ConvexShape>);
|
||||||
static_assert(std::is_move_constructible_v<sf::ConvexShape>);
|
static_assert(std::is_nothrow_move_constructible_v<sf::ConvexShape>);
|
||||||
static_assert(std::is_move_assignable_v<sf::ConvexShape>);
|
static_assert(std::is_nothrow_move_assignable_v<sf::ConvexShape>);
|
||||||
|
|
||||||
TEST_CASE("[Graphics] sf::ConvexShape")
|
TEST_CASE("[Graphics] sf::ConvexShape")
|
||||||
{
|
{
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
static_assert(std::is_copy_constructible_v<sf::RectangleShape>);
|
static_assert(std::is_copy_constructible_v<sf::RectangleShape>);
|
||||||
static_assert(std::is_copy_assignable_v<sf::RectangleShape>);
|
static_assert(std::is_copy_assignable_v<sf::RectangleShape>);
|
||||||
static_assert(std::is_move_constructible_v<sf::RectangleShape>);
|
static_assert(std::is_nothrow_move_constructible_v<sf::RectangleShape>);
|
||||||
static_assert(std::is_move_assignable_v<sf::RectangleShape>);
|
static_assert(std::is_nothrow_move_assignable_v<sf::RectangleShape>);
|
||||||
|
|
||||||
TEST_CASE("[Graphics] sf::RectangleShape")
|
TEST_CASE("[Graphics] sf::RectangleShape")
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,8 @@ static_assert(!std::is_constructible_v<sf::Shape>);
|
|||||||
static_assert(!std::is_copy_constructible_v<sf::Shape>);
|
static_assert(!std::is_copy_constructible_v<sf::Shape>);
|
||||||
static_assert(std::is_copy_assignable_v<sf::Shape>);
|
static_assert(std::is_copy_assignable_v<sf::Shape>);
|
||||||
static_assert(!std::is_move_constructible_v<sf::Shape>);
|
static_assert(!std::is_move_constructible_v<sf::Shape>);
|
||||||
static_assert(std::is_move_assignable_v<sf::Shape>);
|
static_assert(std::is_nothrow_move_assignable_v<sf::Shape>);
|
||||||
|
static_assert(std::has_virtual_destructor_v<sf::Shape>);
|
||||||
|
|
||||||
class TriangleShape : public sf::Shape
|
class TriangleShape : public sf::Shape
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,7 @@ static_assert(std::is_move_constructible_v<sf::Texture>);
|
|||||||
static_assert(!std::is_nothrow_move_constructible_v<sf::Texture>);
|
static_assert(!std::is_nothrow_move_constructible_v<sf::Texture>);
|
||||||
static_assert(std::is_move_assignable_v<sf::Texture>);
|
static_assert(std::is_move_assignable_v<sf::Texture>);
|
||||||
static_assert(!std::is_nothrow_move_assignable_v<sf::Texture>);
|
static_assert(!std::is_nothrow_move_assignable_v<sf::Texture>);
|
||||||
|
static_assert(std::is_nothrow_swappable_v<sf::Texture>);
|
||||||
|
|
||||||
TEST_CASE("[Graphics] sf::Texture" * doctest::skip(skipDisplayTests))
|
TEST_CASE("[Graphics] sf::Texture" * doctest::skip(skipDisplayTests))
|
||||||
{
|
{
|
||||||
|
@ -15,6 +15,7 @@ static_assert(std::is_move_constructible_v<sf::VertexBuffer>);
|
|||||||
static_assert(!std::is_nothrow_move_constructible_v<sf::VertexBuffer>);
|
static_assert(!std::is_nothrow_move_constructible_v<sf::VertexBuffer>);
|
||||||
static_assert(std::is_move_assignable_v<sf::VertexBuffer>);
|
static_assert(std::is_move_assignable_v<sf::VertexBuffer>);
|
||||||
static_assert(!std::is_nothrow_move_assignable_v<sf::VertexBuffer>);
|
static_assert(!std::is_nothrow_move_assignable_v<sf::VertexBuffer>);
|
||||||
|
static_assert(std::is_nothrow_swappable_v<sf::VertexBuffer>);
|
||||||
|
|
||||||
// Skip these tests because they produce flakey failures in CI when using xvfb-run
|
// Skip these tests because they produce flakey failures in CI when using xvfb-run
|
||||||
TEST_CASE("[Graphics] sf::VertexBuffer" * doctest::skip(true))
|
TEST_CASE("[Graphics] sf::VertexBuffer" * doctest::skip(true))
|
||||||
@ -148,7 +149,7 @@ TEST_CASE("[Graphics] sf::VertexBuffer" * doctest::skip(true))
|
|||||||
sf::VertexBuffer vertexBuffer2(sf::PrimitiveType::TriangleStrip, sf::VertexBuffer::Stream);
|
sf::VertexBuffer vertexBuffer2(sf::PrimitiveType::TriangleStrip, sf::VertexBuffer::Stream);
|
||||||
CHECK(vertexBuffer2.create(60));
|
CHECK(vertexBuffer2.create(60));
|
||||||
|
|
||||||
vertexBuffer1.swap(vertexBuffer2);
|
std::swap(vertexBuffer1, vertexBuffer2);
|
||||||
|
|
||||||
CHECK(vertexBuffer1.getVertexCount() == 60);
|
CHECK(vertexBuffer1.getVertexCount() == 60);
|
||||||
CHECK(vertexBuffer1.getNativeHandle() != 0);
|
CHECK(vertexBuffer1.getNativeHandle() != 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user