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
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Virtual destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~Shape() override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the source texture of the shape
|
||||
///
|
||||
|
@ -518,7 +518,7 @@ public:
|
||||
/// \param right Instance to swap with
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void swap(Texture& right);
|
||||
void swap(Texture& right) noexcept;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \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
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \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
|
||||
|
||||
|
||||
|
@ -224,7 +224,7 @@ public:
|
||||
/// \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.
|
||||
@ -338,6 +338,15 @@ private:
|
||||
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
|
||||
|
||||
|
||||
|
@ -126,6 +126,17 @@ endif()
|
||||
sfml_find_package(Freetype INCLUDE "FREETYPE_INCLUDE_DIRS" LINK "FREETYPE_LIBRARY")
|
||||
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
|
||||
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
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Shape::~Shape() = default;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Shape::setTexture(const Texture* texture, bool resetRect)
|
||||
{
|
||||
|
@ -33,10 +33,10 @@
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <SFML/Window/Window.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
@ -45,18 +45,13 @@ namespace
|
||||
// A nested named namespace is used here to allow unity builds of SFML.
|
||||
namespace TextureImpl
|
||||
{
|
||||
std::recursive_mutex idMutex;
|
||||
std::recursive_mutex maximumSizeMutex;
|
||||
|
||||
// Thread-safe unique identifier generator,
|
||||
// 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++;
|
||||
return id.fetch_add(1);
|
||||
}
|
||||
} // namespace TextureImpl
|
||||
} // namespace
|
||||
@ -832,21 +827,18 @@ void Texture::bind(const Texture* texture, CoordinateType coordinateType)
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Texture::getMaximumSize()
|
||||
{
|
||||
std::lock_guard lock(TextureImpl::maximumSizeMutex);
|
||||
|
||||
static bool checked = false;
|
||||
static GLint size = 0;
|
||||
|
||||
if (!checked)
|
||||
static const unsigned int size = []()
|
||||
{
|
||||
checked = true;
|
||||
|
||||
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_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
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <ostream>
|
||||
#include <utility>
|
||||
|
||||
@ -42,8 +41,6 @@ namespace
|
||||
// A nested named namespace is used here to allow unity builds of SFML.
|
||||
namespace VertexBufferImpl
|
||||
{
|
||||
std::recursive_mutex isAvailableMutex;
|
||||
|
||||
GLenum usageToGlEnum(sf::VertexBuffer::Usage 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_buffer, right.m_buffer);
|
||||
@ -333,22 +330,15 @@ VertexBuffer::Usage VertexBuffer::getUsage() const
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VertexBuffer::isAvailable()
|
||||
{
|
||||
std::lock_guard lock(VertexBufferImpl::isAvailableMutex);
|
||||
|
||||
static bool checked = false;
|
||||
static bool available = false;
|
||||
|
||||
if (!checked)
|
||||
static const bool available = []() -> bool
|
||||
{
|
||||
checked = true;
|
||||
|
||||
TransientContextLock contextLock;
|
||||
|
||||
// Make sure that extensions are initialized
|
||||
sf::priv::ensureExtensionsInit();
|
||||
|
||||
available = GLEXT_vertex_buffer_object;
|
||||
}
|
||||
return GLEXT_vertex_buffer_object;
|
||||
}();
|
||||
|
||||
return available;
|
||||
}
|
||||
@ -361,4 +351,11 @@ void VertexBuffer::draw(RenderTarget& target, const RenderStates& states) const
|
||||
target.draw(*this, 0, m_size, states);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void swap(VertexBuffer& left, VertexBuffer& right) noexcept
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
} // namespace sf
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
static_assert(std::is_copy_constructible_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_move_assignable_v<sf::CircleShape>);
|
||||
static_assert(std::is_nothrow_move_constructible_v<sf::CircleShape>);
|
||||
static_assert(std::is_nothrow_move_assignable_v<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_assignable_v<sf::ConvexShape>);
|
||||
static_assert(std::is_move_constructible_v<sf::ConvexShape>);
|
||||
static_assert(std::is_move_assignable_v<sf::ConvexShape>);
|
||||
static_assert(std::is_nothrow_move_constructible_v<sf::ConvexShape>);
|
||||
static_assert(std::is_nothrow_move_assignable_v<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_assignable_v<sf::RectangleShape>);
|
||||
static_assert(std::is_move_constructible_v<sf::RectangleShape>);
|
||||
static_assert(std::is_move_assignable_v<sf::RectangleShape>);
|
||||
static_assert(std::is_nothrow_move_constructible_v<sf::RectangleShape>);
|
||||
static_assert(std::is_nothrow_move_assignable_v<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_assignable_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
|
||||
{
|
||||
|
@ -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_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))
|
||||
{
|
||||
|
@ -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_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
|
||||
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);
|
||||
CHECK(vertexBuffer2.create(60));
|
||||
|
||||
vertexBuffer1.swap(vertexBuffer2);
|
||||
std::swap(vertexBuffer1, vertexBuffer2);
|
||||
|
||||
CHECK(vertexBuffer1.getVertexCount() == 60);
|
||||
CHECK(vertexBuffer1.getNativeHandle() != 0);
|
||||
|
Loading…
Reference in New Issue
Block a user