Use smart pointers to manage memory

This commit is contained in:
Vittorio Romeo 2021-12-21 18:57:38 +01:00
parent 257c78f07a
commit f6de7eca40
44 changed files with 359 additions and 396 deletions

View File

@ -3,7 +3,7 @@
// Headers
////////////////////////////////////////////////////////////
#include "Effect.hpp"
#include <vector>
#include <array>
#include <cmath>
@ -357,12 +357,20 @@ int main()
Effect::setFont(font);
// Create the effects
std::vector<Effect*> effects;
effects.push_back(new Pixelate);
effects.push_back(new WaveBlur);
effects.push_back(new StormBlink);
effects.push_back(new Edge);
effects.push_back(new Geometry);
Pixelate pixelateEffect;
WaveBlur waveBlurEffect;
StormBlink stormBlinkEffect;
Edge edgeEffect;
Geometry geometryEffect;
const std::array<Effect*, 5> effects{
&pixelateEffect,
&waveBlurEffect,
&stormBlinkEffect,
&edgeEffect,
&geometryEffect
};
std::size_t current = 0;
// Initialize them
@ -456,9 +464,5 @@ int main()
window.display();
}
// delete the effects
for (Effect* effect : effects)
delete effect;
return EXIT_SUCCESS;
}

View File

@ -30,6 +30,7 @@
////////////////////////////////////////////////////////////
#include <SFML/Audio/Export.hpp>
#include <SFML/System/Time.hpp>
#include <memory>
#include <string>
#include <cstddef>
@ -218,13 +219,28 @@ public:
void close();
private:
////////////////////////////////////////////////////////////
/// \brief Deleter for input streams that only conditionally deletes
///
////////////////////////////////////////////////////////////
struct StreamDeleter
{
StreamDeleter(bool theOwned);
// To accept ownership transfer from usual std::unique_ptr<T>
template <typename T>
StreamDeleter(const std::default_delete<T>&);
void operator()(InputStream* ptr) const;
bool owned;
};
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SoundFileReader* m_reader; //!< Reader that handles I/O on the file's format
InputStream* m_stream; //!< Input stream used to access the file's data
bool m_streamOwned; //!< Is the stream internal or external?
std::unique_ptr<SoundFileReader> m_reader; //!< Reader that handles I/O on the file's format
std::unique_ptr<InputStream, StreamDeleter> m_stream; //!< Input stream used to access the file's data
Uint64 m_sampleOffset; //!< Sample Read Position
Uint64 m_sampleCount; //!< Total number of samples in the file
unsigned int m_channelCount; //!< Number of channels of the sound

View File

@ -29,6 +29,7 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio/Export.hpp>
#include <memory>
#include <string>
@ -104,7 +105,7 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SoundFileWriter* m_writer; //!< Writer that handles I/O on the file's format
std::unique_ptr<SoundFileWriter> m_writer; //!< Writer that handles I/O on the file's format
};
} // namespace sf

View File

@ -29,6 +29,7 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio/Export.hpp>
#include <memory>
#include <string>
#include <vector>
@ -86,8 +87,6 @@ public:
////////////////////////////////////////////////////////////
/// \brief Instantiate the right reader for the given file on disk
///
/// It's up to the caller to release the returned reader
///
/// \param filename Path of the sound file
///
/// \return A new sound file reader that can read the given file, or null if no reader can handle it
@ -95,13 +94,11 @@ public:
/// \see createReaderFromMemory, createReaderFromStream
///
////////////////////////////////////////////////////////////
static SoundFileReader* createReaderFromFilename(const std::string& filename);
static std::unique_ptr<SoundFileReader> createReaderFromFilename(const std::string& filename);
////////////////////////////////////////////////////////////
/// \brief Instantiate the right codec for the given file in memory
///
/// It's up to the caller to release the returned reader
///
/// \param data Pointer to the file data in memory
/// \param sizeInBytes Total size of the file data, in bytes
///
@ -110,13 +107,11 @@ public:
/// \see createReaderFromFilename, createReaderFromStream
///
////////////////////////////////////////////////////////////
static SoundFileReader* createReaderFromMemory(const void* data, std::size_t sizeInBytes);
static std::unique_ptr<SoundFileReader> createReaderFromMemory(const void* data, std::size_t sizeInBytes);
////////////////////////////////////////////////////////////
/// \brief Instantiate the right codec for the given file in stream
///
/// It's up to the caller to release the returned reader
///
/// \param stream Source stream to read from
///
/// \return A new sound file codec that can read the given file, or null if no codec can handle it
@ -124,19 +119,17 @@ public:
/// \see createReaderFromFilename, createReaderFromMemory
///
////////////////////////////////////////////////////////////
static SoundFileReader* createReaderFromStream(InputStream& stream);
static std::unique_ptr<SoundFileReader> createReaderFromStream(InputStream& stream);
////////////////////////////////////////////////////////////
/// \brief Instantiate the right writer for the given file on disk
///
/// It's up to the caller to release the returned writer
///
/// \param filename Path of the sound file
///
/// \return A new sound file writer that can write given file, or null if no writer can handle it
///
////////////////////////////////////////////////////////////
static SoundFileWriter* createWriterFromFilename(const std::string& filename);
static std::unique_ptr<SoundFileWriter> createWriterFromFilename(const std::string& filename);
private:
@ -146,14 +139,14 @@ private:
struct ReaderFactory
{
bool (*check)(InputStream&);
SoundFileReader* (*create)();
std::unique_ptr<SoundFileReader> (*create)();
};
using ReaderFactoryArray = std::vector<ReaderFactory>;
struct WriterFactory
{
bool (*check)(const std::string&);
SoundFileWriter* (*create)();
std::unique_ptr<SoundFileWriter> (*create)();
};
using WriterFactoryArray = std::vector<WriterFactory>;

View File

@ -31,8 +31,8 @@ namespace sf
{
namespace priv
{
template <typename T> SoundFileReader* createReader() {return new T;}
template <typename T> SoundFileWriter* createWriter() {return new T;}
template <typename T> std::unique_ptr<SoundFileReader> createReader() { return std::make_unique<T>(); }
template <typename T> std::unique_ptr<SoundFileWriter> createWriter() { return std::make_unique<T>(); }
}
////////////////////////////////////////////////////////////

View File

@ -32,11 +32,19 @@
#include <SFML/Graphics/Glyph.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <unordered_map>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#ifdef SFML_SYSTEM_ANDROID
namespace sf::priv
{
class ResourceStream;
}
#endif
namespace sf
{
class InputStream;
@ -387,22 +395,19 @@ private:
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
class FontHandles;
using PageTable = std::unordered_map<unsigned int, Page>; //!< Table mapping a character size to its page (texture)
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
void* m_library; //!< Pointer to the internal library interface (it is typeless to avoid exposing implementation details)
void* m_face; //!< Pointer to the internal font face (it is typeless to avoid exposing implementation details)
void* m_streamRec; //!< Pointer to the stream rec instance (it is typeless to avoid exposing implementation details)
void* m_stroker; //!< Pointer to the stroker (it is typeless to avoid exposing implementation details)
int* m_refCount; //!< Reference counter used by implicit sharing
std::shared_ptr<FontHandles> m_font; //!< Shared information about the internal font instance
bool m_isSmooth; //!< Status of the smooth filter
Info m_info; //!< Information about the font
mutable PageTable m_pages; //!< Table containing the glyphs pages by character size
mutable std::vector<Uint8> m_pixelBuffer; //!< Pixel buffer holding a glyph's pixels before being written to the texture
#ifdef SFML_SYSTEM_ANDROID
void* m_stream; //!< Asset file streamer (if loaded from file)
std::unique_ptr<priv::ResourceStream> m_stream; //!< Asset file streamer (if loaded from file)
#endif
};

View File

@ -32,6 +32,7 @@
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <memory>
namespace sf
@ -228,7 +229,7 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
priv::RenderTextureImpl* m_impl; //!< Platform/hardware specific implementation
std::unique_ptr<priv::RenderTextureImpl> m_impl; //!< Platform/hardware specific implementation
Texture m_texture; //!< Target texture to draw on
};

View File

@ -30,6 +30,7 @@
////////////////////////////////////////////////////////////
#include <SFML/Network/Export.hpp>
#include <SFML/System/Time.hpp>
#include <memory>
namespace sf
@ -50,6 +51,12 @@ public:
////////////////////////////////////////////////////////////
SocketSelector();
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~SocketSelector();
////////////////////////////////////////////////////////////
/// \brief Copy constructor
///
@ -58,12 +65,6 @@ public:
////////////////////////////////////////////////////////////
SocketSelector(const SocketSelector& copy);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~SocketSelector();
////////////////////////////////////////////////////////////
/// \brief Add a new socket to the selector
///
@ -158,7 +159,7 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketSelectorImpl* m_impl; //!< Opaque pointer to the implementation (which requires OS-specific types)
std::unique_ptr<SocketSelectorImpl> m_impl; //!< Opaque pointer to the implementation (which requires OS-specific types)
};
} // namespace sf
@ -203,7 +204,7 @@ private:
/// listener.listen(55001);
///
/// // Create a list to store the future clients
/// std::list<sf::TcpSocket*> clients;
/// std::list<std::unique_ptr<sf::TcpSocket>> clients;
///
/// // Create a selector
/// sf::SocketSelector selector;
@ -221,28 +222,27 @@ private:
/// if (selector.isReady(listener))
/// {
/// // The listener is ready: there is a pending connection
/// sf::TcpSocket* client = new sf::TcpSocket;
/// auto client = std::make_unique<sf::TcpSocket>();
/// if (listener.accept(*client) == sf::Socket::Done)
/// {
/// // Add the new client to the clients list
/// clients.push_back(client);
///
/// // Add the new client to the selector so that we will
/// // be notified when he sends something
/// selector.add(*client);
///
/// // Add the new client to the clients list
/// clients.push_back(std::move(client));
/// }
/// else
/// {
/// // Error, we won't get a new connection, delete the socket
/// delete client;
/// client.reset();
/// }
/// }
/// else
/// {
/// // The listener socket is not ready, test all other sockets (the clients)
/// for (auto it = clients.begin(); it != clients.end(); ++it)
/// for (sf::TcpSocket& client : clients)
/// {
/// sf::TcpSocket& client = **it;
/// if (selector.isReady(client))
/// {
/// // The client has sent some data, we can receive it

View File

@ -31,8 +31,9 @@
#include <SFML/Config.hpp>
#include <SFML/System/Export.hpp>
#include <SFML/System/InputStream.hpp>
#include <cstdio>
#include <memory>
#include <string>
#include <cstdio>
#ifdef SFML_SYSTEM_ANDROID
namespace sf
@ -134,7 +135,7 @@ private:
// Member data
////////////////////////////////////////////////////////////
#ifdef SFML_SYSTEM_ANDROID
priv::ResourceStream* m_file;
std::unique_ptr<priv::ResourceStream> m_file;
#else
std::FILE* m_file; //!< stdio file stream
#endif

View File

@ -31,6 +31,7 @@
#include <SFML/Window/Export.hpp>
#include <SFML/Window/GlResource.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <memory>
namespace sf
@ -161,7 +162,7 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
priv::GlContext* m_context; //!< Internal OpenGL context
std::unique_ptr<priv::GlContext> m_context; //!< Internal OpenGL context
};
} // namespace sf

View File

@ -30,6 +30,7 @@
////////////////////////////////////////////////////////////
#include <SFML/Window/Export.hpp>
#include <SFML/System/Vector2.hpp>
#include <memory>
namespace sf
{
@ -209,7 +210,7 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
priv::CursorImpl* m_impl; //!< Platform-specific implementation of the cursor
std::unique_ptr<priv::CursorImpl> m_impl; //!< Platform-specific implementation of the cursor
};
} // namespace sf

View File

@ -31,6 +31,7 @@
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/Window/GlResource.hpp>
#include <SFML/Window/WindowBase.hpp>
#include <memory>
namespace sf
@ -276,7 +277,7 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
priv::GlContext* m_context; //!< Platform-specific implementation of the OpenGL context
std::unique_ptr<priv::GlContext> m_context; //!< Platform-specific implementation of the OpenGL context
Clock m_clock; //!< Clock for measuring the elapsed time between frames
Time m_frameTimeLimit; //!< Current framerate limit
};

View File

@ -36,6 +36,7 @@
#include <SFML/Window/WindowStyle.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/System/Vector2.hpp>
#include <memory>
namespace sf
@ -482,7 +483,7 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
priv::WindowImpl* m_impl; //!< Platform-specific implementation of the window
std::unique_ptr<priv::WindowImpl> m_impl; //!< Platform-specific implementation of the window
Vector2u m_size; //!< Current size of the window
};

View File

@ -27,6 +27,7 @@
////////////////////////////////////////////////////////////
#include <SFML/Audio/AlResource.hpp>
#include <SFML/Audio/AudioDevice.hpp>
#include <memory>
#include <mutex>
@ -39,7 +40,7 @@ namespace
// The audio device is instantiated on demand rather than at global startup,
// which solves a lot of weird crashes and errors.
// It is destroyed when it is no longer needed.
sf::priv::AudioDevice* globalDevice;
std::unique_ptr<sf::priv::AudioDevice> globalDevice;
}
@ -53,7 +54,7 @@ AlResource::AlResource()
// If this is the very first resource, trigger the global device initialization
if (count == 0)
globalDevice = new priv::AudioDevice;
globalDevice = std::make_unique<priv::AudioDevice>();
// Increment the resources counter
count++;
@ -71,7 +72,7 @@ AlResource::~AlResource()
// If there's no more resource alive, we can destroy the device
if (count == 0)
delete globalDevice;
globalDevice.reset();
}
} // namespace sf

View File

@ -38,12 +38,35 @@
namespace sf
{
////////////////////////////////////////////////////////////
InputSoundFile::StreamDeleter::StreamDeleter(bool theOwned) : owned{theOwned}
{
}
////////////////////////////////////////////////////////////
template <typename T>
InputSoundFile::StreamDeleter::StreamDeleter(const std::default_delete<T>&)
: owned{true}
{
}
////////////////////////////////////////////////////////////
void InputSoundFile::StreamDeleter::operator()(InputStream* ptr) const
{
if (owned)
std::default_delete<InputStream>{}(ptr);
}
////////////////////////////////////////////////////////////
InputSoundFile::InputSoundFile() :
m_reader (nullptr),
m_stream (nullptr),
m_streamOwned (false),
m_sampleOffset (0),
m_reader (),
m_stream (nullptr, false),
m_sampleOffset(0),
m_sampleCount (0),
m_channelCount(0),
m_sampleRate (0)
@ -66,29 +89,25 @@ bool InputSoundFile::openFromFile(const std::string& filename)
close();
// Find a suitable reader for the file type
m_reader = SoundFileFactory::createReaderFromFilename(filename);
if (!m_reader)
auto reader = SoundFileFactory::createReaderFromFilename(filename);
if (!reader)
return false;
// Wrap the file into a stream
auto* file = new FileInputStream;
m_stream = file;
m_streamOwned = true;
auto file = std::make_unique<FileInputStream>();
// Open it
if (!file->open(filename))
{
close();
return false;
}
// Pass the stream to the reader
SoundFileReader::Info info;
if (!m_reader->open(*file, info))
{
close();
if (!reader->open(*file, info))
return false;
}
// Take ownership of successfully opened reader and stream
m_reader = std::move(reader);
m_stream = std::move(file);
// Retrieve the attributes of the open sound file
m_sampleCount = info.sampleCount;
@ -106,25 +125,24 @@ bool InputSoundFile::openFromMemory(const void* data, std::size_t sizeInBytes)
close();
// Find a suitable reader for the file type
m_reader = SoundFileFactory::createReaderFromMemory(data, sizeInBytes);
if (!m_reader)
auto reader = SoundFileFactory::createReaderFromMemory(data, sizeInBytes);
if (!reader)
return false;
// Wrap the memory file into a stream
auto* memory = new MemoryInputStream;
m_stream = memory;
m_streamOwned = true;
auto memory = std::make_unique<MemoryInputStream>();
// Open it
memory->open(data, sizeInBytes);
// Pass the stream to the reader
SoundFileReader::Info info;
if (!m_reader->open(*memory, info))
{
close();
if (!reader->open(*memory, info))
return false;
}
// Take ownership of successfully opened reader and stream
m_reader = std::move(reader);
m_stream = std::move(memory);
// Retrieve the attributes of the open sound file
m_sampleCount = info.sampleCount;
@ -142,14 +160,10 @@ bool InputSoundFile::openFromStream(InputStream& stream)
close();
// Find a suitable reader for the file type
m_reader = SoundFileFactory::createReaderFromStream(stream);
if (!m_reader)
auto reader = SoundFileFactory::createReaderFromStream(stream);
if (!reader)
return false;
// store the stream
m_stream = &stream;
m_streamOwned = false;
// Don't forget to reset the stream to its beginning before re-opening it
if (stream.seek(0) != 0)
{
@ -159,11 +173,12 @@ bool InputSoundFile::openFromStream(InputStream& stream)
// Pass the stream to the reader
SoundFileReader::Info info;
if (!m_reader->open(stream, info))
{
close();
if (!reader->open(stream, info))
return false;
}
// Take ownership of reader and store a reference to the stream without taking ownership
m_reader = std::move(reader);
m_stream = {&stream, false};
// Retrieve the attributes of the open sound file
m_sampleCount = info.sampleCount;
@ -259,19 +274,13 @@ Uint64 InputSoundFile::read(Int16* samples, Uint64 maxCount)
void InputSoundFile::close()
{
// Destroy the reader
delete m_reader;
m_reader = nullptr;
m_reader.reset();
// Destroy the stream if we own it
if (m_streamOwned)
{
delete m_stream;
m_streamOwned = false;
}
m_stream = nullptr;
m_sampleOffset = 0;
m_stream.reset();
// Reset the sound file attributes
m_sampleOffset = 0;
m_sampleCount = 0;
m_channelCount = 0;
m_sampleRate = 0;

View File

@ -81,8 +81,7 @@ void OutputSoundFile::write(const Int16* samples, Uint64 count)
void OutputSoundFile::close()
{
// Destroy the reader
delete m_writer;
m_writer = nullptr;
m_writer.reset();
}
} // namespace sf

View File

@ -65,7 +65,7 @@ SoundFileFactory::WriterFactoryArray SoundFileFactory::s_writers;
////////////////////////////////////////////////////////////
SoundFileReader* SoundFileFactory::createReaderFromFilename(const std::string& filename)
std::unique_ptr<SoundFileReader> SoundFileFactory::createReaderFromFilename(const std::string& filename)
{
// Register the built-in readers/writers on first call
ensureDefaultReadersWritersRegistered();
@ -97,7 +97,7 @@ SoundFileReader* SoundFileFactory::createReaderFromFilename(const std::string& f
////////////////////////////////////////////////////////////
SoundFileReader* SoundFileFactory::createReaderFromMemory(const void* data, std::size_t sizeInBytes)
std::unique_ptr<SoundFileReader> SoundFileFactory::createReaderFromMemory(const void* data, std::size_t sizeInBytes)
{
// Register the built-in readers/writers on first call
ensureDefaultReadersWritersRegistered();
@ -126,7 +126,7 @@ SoundFileReader* SoundFileFactory::createReaderFromMemory(const void* data, std:
////////////////////////////////////////////////////////////
SoundFileReader* SoundFileFactory::createReaderFromStream(InputStream& stream)
std::unique_ptr<SoundFileReader> SoundFileFactory::createReaderFromStream(InputStream& stream)
{
// Register the built-in readers/writers on first call
ensureDefaultReadersWritersRegistered();
@ -151,7 +151,7 @@ SoundFileReader* SoundFileFactory::createReaderFromStream(InputStream& stream)
////////////////////////////////////////////////////////////
SoundFileWriter* SoundFileFactory::createWriterFromFilename(const std::string& filename)
std::unique_ptr<SoundFileWriter> SoundFileFactory::createWriterFromFilename(const std::string& filename)
{
// Register the built-in readers/writers on first call
ensureDefaultReadersWritersRegistered();

View File

@ -38,6 +38,7 @@
#include FT_OUTLINE_H
#include FT_BITMAP_H
#include FT_STROKER_H
#include <type_traits>
#include <cstdlib>
#include <cstring>
#include <cmath>
@ -83,43 +84,45 @@ namespace
namespace sf
{
////////////////////////////////////////////////////////////
class Font::FontHandles
{
private:
// Default constructible deleter functor
struct Deleter
{
void operator()(FT_Library theLibrary) { FT_Done_FreeType(theLibrary); }
void operator()(FT_Face theFace) { FT_Done_Face(theFace); }
void operator()(FT_Stroker theStroker) { FT_Stroker_Done(theStroker); }
};
public:
std::unique_ptr<std::remove_pointer_t<FT_Library>, Deleter> library; //< Pointer to the internal library interface
std::unique_ptr<FT_StreamRec> streamRec; //< Pointer to the stream rec instance
std::unique_ptr<std::remove_pointer_t<FT_Face>, Deleter> face; //< Pointer to the internal font face
std::unique_ptr<std::remove_pointer_t<FT_Stroker>, Deleter> stroker; //< Pointer to the stroker
};
////////////////////////////////////////////////////////////
Font::Font() :
m_library (nullptr),
m_face (nullptr),
m_streamRec(nullptr),
m_stroker (nullptr),
m_refCount (nullptr),
m_font (),
m_isSmooth (true),
m_info ()
{
#ifdef SFML_SYSTEM_ANDROID
m_stream = nullptr;
#endif
}
////////////////////////////////////////////////////////////
Font::Font(const Font& copy) :
m_library (copy.m_library),
m_face (copy.m_face),
m_streamRec (copy.m_streamRec),
m_stroker (copy.m_stroker),
m_refCount (copy.m_refCount),
m_font (copy.m_font),
m_isSmooth (copy.m_isSmooth),
m_info (copy.m_info),
m_pages (copy.m_pages),
m_pixelBuffer(copy.m_pixelBuffer)
{
#ifdef SFML_SYSTEM_ANDROID
m_stream = nullptr;
#endif
// Note: as FreeType doesn't provide functions for copying/cloning,
// we must share all the FreeType pointers
if (m_refCount)
(*m_refCount)++;
}
@ -127,13 +130,6 @@ m_pixelBuffer(copy.m_pixelBuffer)
Font::~Font()
{
cleanup();
#ifdef SFML_SYSTEM_ANDROID
if (m_stream)
delete static_cast<priv::ResourceStream*>(m_stream);
#endif
}
@ -144,7 +140,8 @@ bool Font::loadFromFile(const std::string& filename)
// Cleanup the previous resources
cleanup();
m_refCount = new int(1);
auto font = std::make_unique<FontHandles>();
// Initialize FreeType
// Note: we initialize FreeType for every font instance in order to avoid having a single
@ -155,37 +152,35 @@ bool Font::loadFromFile(const std::string& filename)
err() << "Failed to load font \"" << filename << "\" (failed to initialize FreeType)" << std::endl;
return false;
}
m_library = library;
font->library.reset(library);
// Load the new font face from the specified file
FT_Face face;
if (FT_New_Face(static_cast<FT_Library>(m_library), filename.c_str(), 0, &face) != 0)
if (FT_New_Face(library, filename.c_str(), 0, &face) != 0)
{
err() << "Failed to load font \"" << filename << "\" (failed to create the font face)" << std::endl;
return false;
}
font->face.reset(face);
// Load the stroker that will be used to outline the font
FT_Stroker stroker;
if (FT_Stroker_New(static_cast<FT_Library>(m_library), &stroker) != 0)
if (FT_Stroker_New(library, &stroker) != 0)
{
err() << "Failed to load font \"" << filename << "\" (failed to create the stroker)" << std::endl;
FT_Done_Face(face);
return false;
}
font->stroker.reset(stroker);
// Select the unicode character map
if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != 0)
{
err() << "Failed to load font \"" << filename << "\" (failed to set the Unicode character set)" << std::endl;
FT_Stroker_Done(stroker);
FT_Done_Face(face);
return false;
}
// Store the loaded font in our ugly void* :)
m_stroker = stroker;
m_face = face;
// Store the loaded font handles
m_font = std::move(font);
// Store the font information
m_info.family = face->family_name ? face->family_name : std::string();
@ -194,11 +189,8 @@ bool Font::loadFromFile(const std::string& filename)
#else
if (m_stream)
delete static_cast<priv::ResourceStream*>(m_stream);
m_stream = new priv::ResourceStream(filename);
return loadFromStream(*static_cast<priv::ResourceStream*>(m_stream));
m_stream = std::make_unique<priv::ResourceStream>(filename);
return loadFromStream(*m_stream);
#endif
}
@ -209,7 +201,8 @@ bool Font::loadFromMemory(const void* data, std::size_t sizeInBytes)
{
// Cleanup the previous resources
cleanup();
m_refCount = new int(1);
auto font = std::make_unique<FontHandles>();
// Initialize FreeType
// Note: we initialize FreeType for every font instance in order to avoid having a single
@ -220,37 +213,35 @@ bool Font::loadFromMemory(const void* data, std::size_t sizeInBytes)
err() << "Failed to load font from memory (failed to initialize FreeType)" << std::endl;
return false;
}
m_library = library;
font->library.reset(library);
// Load the new font face from the specified file
FT_Face face;
if (FT_New_Memory_Face(static_cast<FT_Library>(m_library), reinterpret_cast<const FT_Byte*>(data), static_cast<FT_Long>(sizeInBytes), 0, &face) != 0)
if (FT_New_Memory_Face(library, reinterpret_cast<const FT_Byte*>(data), static_cast<FT_Long>(sizeInBytes), 0, &face) != 0)
{
err() << "Failed to load font from memory (failed to create the font face)" << std::endl;
return false;
}
font->face.reset(face);
// Load the stroker that will be used to outline the font
FT_Stroker stroker;
if (FT_Stroker_New(static_cast<FT_Library>(m_library), &stroker) != 0)
if (FT_Stroker_New(library, &stroker) != 0)
{
err() << "Failed to load font from memory (failed to create the stroker)" << std::endl;
FT_Done_Face(face);
return false;
}
font->stroker.reset(stroker);
// Select the Unicode character map
if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != 0)
{
err() << "Failed to load font from memory (failed to set the Unicode character set)" << std::endl;
FT_Stroker_Done(stroker);
FT_Done_Face(face);
return false;
}
// Store the loaded font in our ugly void* :)
m_stroker = stroker;
m_face = face;
// Store the loaded font handles
m_font = std::move(font);
// Store the font information
m_info.family = face->family_name ? face->family_name : std::string();
@ -264,7 +255,8 @@ bool Font::loadFromStream(InputStream& stream)
{
// Cleanup the previous resources
cleanup();
m_refCount = new int(1);
auto font = std::make_unique<FontHandles>();
// Initialize FreeType
// Note: we initialize FreeType for every font instance in order to avoid having a single
@ -275,7 +267,7 @@ bool Font::loadFromStream(InputStream& stream)
err() << "Failed to load font from stream (failed to initialize FreeType)" << std::endl;
return false;
}
m_library = library;
font->library.reset(library);
// Make sure that the stream's reading position is at the beginning
if (stream.seek(0) == -1)
@ -285,54 +277,48 @@ bool Font::loadFromStream(InputStream& stream)
}
// Prepare a wrapper for our stream, that we'll pass to FreeType callbacks
auto* rec = new FT_StreamRec;
std::memset(rec, 0, sizeof(*rec));
rec->base = nullptr;
rec->size = static_cast<unsigned long>(stream.getSize());
rec->pos = 0;
rec->descriptor.pointer = &stream;
rec->read = &read;
rec->close = &close;
font->streamRec = std::make_unique<FT_StreamRec>();
std::memset(font->streamRec.get(), 0, sizeof(*font->streamRec));
font->streamRec->base = nullptr;
font->streamRec->size = static_cast<unsigned long>(stream.getSize());
font->streamRec->pos = 0;
font->streamRec->descriptor.pointer = &stream;
font->streamRec->read = &read;
font->streamRec->close = &close;
// Setup the FreeType callbacks that will read our stream
FT_Open_Args args;
args.flags = FT_OPEN_STREAM;
args.stream = rec;
args.stream = font->streamRec.get();
args.driver = nullptr;
// Load the new font face from the specified stream
FT_Face face;
if (FT_Open_Face(static_cast<FT_Library>(m_library), &args, 0, &face) != 0)
if (FT_Open_Face(library, &args, 0, &face) != 0)
{
err() << "Failed to load font from stream (failed to create the font face)" << std::endl;
delete rec;
return false;
}
font->face.reset(face);
// Load the stroker that will be used to outline the font
FT_Stroker stroker;
if (FT_Stroker_New(static_cast<FT_Library>(m_library), &stroker) != 0)
if (FT_Stroker_New(library, &stroker) != 0)
{
err() << "Failed to load font from stream (failed to create the stroker)" << std::endl;
FT_Done_Face(face);
delete rec;
return false;
}
font->stroker.reset(stroker);
// Select the Unicode character map
if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != 0)
{
err() << "Failed to load font from stream (failed to set the Unicode character set)" << std::endl;
FT_Done_Face(face);
FT_Stroker_Done(stroker);
delete rec;
return false;
}
// Store the loaded font in our ugly void* :)
m_stroker = stroker;
m_face = face;
m_streamRec = rec;
// Store the loaded font handles
m_font = std::move(font);
// Store the font information
m_info.family = face->family_name ? face->family_name : std::string();
@ -355,7 +341,7 @@ const Glyph& Font::getGlyph(Uint32 codePoint, unsigned int characterSize, bool b
GlyphTable& glyphs = m_pages[characterSize].glyphs;
// Build the key by combining the glyph index (based on code point), bold flag, and outline thickness
Uint64 key = combine(outlineThickness, bold, FT_Get_Char_Index(static_cast<FT_Face>(m_face), codePoint));
Uint64 key = combine(outlineThickness, bold, FT_Get_Char_Index(m_font->face.get(), codePoint));
// Search the glyph into the cache
if (auto it = glyphs.find(key); it != glyphs.end())
@ -375,7 +361,7 @@ const Glyph& Font::getGlyph(Uint32 codePoint, unsigned int characterSize, bool b
////////////////////////////////////////////////////////////
bool Font::hasGlyph(Uint32 codePoint) const
{
return FT_Get_Char_Index(static_cast<FT_Face>(m_face), codePoint) != 0;
return FT_Get_Char_Index(m_font->face.get(), codePoint) != 0;
}
@ -386,7 +372,7 @@ float Font::getKerning(Uint32 first, Uint32 second, unsigned int characterSize,
if (first == 0 || second == 0)
return 0.f;
auto face = static_cast<FT_Face>(m_face);
auto face = m_font->face.get();
if (face && setCurrentSize(characterSize))
{
@ -423,7 +409,7 @@ float Font::getKerning(Uint32 first, Uint32 second, unsigned int characterSize,
////////////////////////////////////////////////////////////
float Font::getLineSpacing(unsigned int characterSize) const
{
auto face = static_cast<FT_Face>(m_face);
auto face = m_font->face.get();
if (face && setCurrentSize(characterSize))
{
@ -439,7 +425,7 @@ float Font::getLineSpacing(unsigned int characterSize) const
////////////////////////////////////////////////////////////
float Font::getUnderlinePosition(unsigned int characterSize) const
{
auto face = static_cast<FT_Face>(m_face);
auto face = m_font->face.get();
if (face && setCurrentSize(characterSize))
{
@ -459,7 +445,7 @@ float Font::getUnderlinePosition(unsigned int characterSize) const
////////////////////////////////////////////////////////////
float Font::getUnderlineThickness(unsigned int characterSize) const
{
auto face = static_cast<FT_Face>(m_face);
auto face = m_font->face.get();
if (face && setCurrentSize(characterSize))
{
@ -508,11 +494,7 @@ Font& Font::operator =(const Font& right)
{
Font temp(right);
std::swap(m_library, temp.m_library);
std::swap(m_face, temp.m_face);
std::swap(m_streamRec, temp.m_streamRec);
std::swap(m_stroker, temp.m_stroker);
std::swap(m_refCount, temp.m_refCount);
std::swap(m_font, temp.m_font);
std::swap(m_isSmooth, temp.m_isSmooth);
std::swap(m_info, temp.m_info);
std::swap(m_pages, temp.m_pages);
@ -529,42 +511,10 @@ Font& Font::operator =(const Font& right)
////////////////////////////////////////////////////////////
void Font::cleanup()
{
// Check if we must destroy the FreeType pointers
if (m_refCount)
{
// Decrease the reference counter
(*m_refCount)--;
// Free the resources only if we are the last owner
if (*m_refCount == 0)
{
// Delete the reference counter
delete m_refCount;
// Destroy the stroker
if (m_stroker)
FT_Stroker_Done(static_cast<FT_Stroker>(m_stroker));
// Destroy the font face
if (m_face)
FT_Done_Face(static_cast<FT_Face>(m_face));
// Destroy the stream rec instance, if any (must be done after FT_Done_Face!)
if (m_streamRec)
delete static_cast<FT_StreamRec*>(m_streamRec);
// Close the library
if (m_library)
FT_Done_FreeType(static_cast<FT_Library>(m_library));
}
}
// Drop ownership of shared FreeType pointers
m_font.reset();
// Reset members
m_library = nullptr;
m_face = nullptr;
m_stroker = nullptr;
m_streamRec = nullptr;
m_refCount = nullptr;
m_pages.clear();
std::vector<Uint8>().swap(m_pixelBuffer);
}
@ -576,8 +526,8 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f
// The glyph to return
Glyph glyph;
// First, transform our ugly void* to a FT_Face
auto face = static_cast<FT_Face>(m_face);
// First, get our FT_Face
auto face = m_font->face.get();
if (!face)
return glyph;
@ -610,7 +560,7 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f
if (outlineThickness != 0)
{
auto stroker = static_cast<FT_Stroker>(m_stroker);
auto stroker = m_font->stroker.get();
FT_Stroker_Set(stroker, static_cast<FT_Fixed>(outlineThickness * static_cast<float>(1 << 6)), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
FT_Glyph_Stroke(&glyphDesc, stroker, true);
@ -628,7 +578,7 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f
if (!outline)
{
if (bold)
FT_Bitmap_Embolden(static_cast<FT_Library>(m_library), &bitmap, weight, weight);
FT_Bitmap_Embolden(m_font->library.get(), &bitmap, weight, weight);
if (outlineThickness != 0)
err() << "Failed to outline glyph (no fallback available)" << std::endl;
@ -814,7 +764,7 @@ bool Font::setCurrentSize(unsigned int characterSize) const
// FT_Set_Pixel_Sizes is an expensive function, so we must call it
// only when necessary to avoid killing performances
auto face = static_cast<FT_Face>(m_face);
auto face = m_font->face.get();
FT_UShort currentSize = face->size->metrics.x_ppem;
if (currentSize != characterSize)

View File

@ -29,23 +29,17 @@
#include <SFML/Graphics/RenderTextureImplFBO.hpp>
#include <SFML/Graphics/RenderTextureImplDefault.hpp>
#include <SFML/System/Err.hpp>
#include <memory>
namespace sf
{
////////////////////////////////////////////////////////////
RenderTexture::RenderTexture() :
m_impl(nullptr)
{
}
RenderTexture::RenderTexture() = default;
////////////////////////////////////////////////////////////
RenderTexture::~RenderTexture()
{
delete m_impl;
}
RenderTexture::~RenderTexture() = default;
////////////////////////////////////////////////////////////
@ -65,11 +59,10 @@ bool RenderTexture::create(unsigned int width, unsigned int height, const Contex
setSmooth(false);
// Create the implementation
delete m_impl;
if (priv::RenderTextureImplFBO::isAvailable())
{
// Use frame-buffer object (FBO)
m_impl = new priv::RenderTextureImplFBO;
m_impl = std::make_unique<priv::RenderTextureImplFBO>();
// Mark the texture as being a framebuffer object attachment
m_texture.m_fboAttachment = true;
@ -77,7 +70,7 @@ bool RenderTexture::create(unsigned int width, unsigned int height, const Contex
else
{
// Use default implementation
m_impl = new priv::RenderTextureImplDefault;
m_impl = std::make_unique<priv::RenderTextureImplDefault>();
}
// Initialize the render texture

View File

@ -29,6 +29,7 @@
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Graphics/TextureSaver.hpp>
#include <SFML/Window/Context.hpp>
#include <memory>
namespace sf
@ -37,7 +38,7 @@ namespace priv
{
////////////////////////////////////////////////////////////
RenderTextureImplDefault::RenderTextureImplDefault() :
m_context(nullptr),
m_context(),
m_width (0),
m_height (0)
{
@ -46,11 +47,7 @@ m_height (0)
////////////////////////////////////////////////////////////
RenderTextureImplDefault::~RenderTextureImplDefault()
{
// Destroy the context
delete m_context;
}
RenderTextureImplDefault::~RenderTextureImplDefault() = default;
////////////////////////////////////////////////////////////
@ -71,7 +68,7 @@ bool RenderTextureImplDefault::create(unsigned int width, unsigned int height, u
m_height = height;
// Create the in-memory OpenGL context
m_context = new Context(settings, width, height);
m_context = std::make_unique<Context>(settings, width, height);
return true;
}

View File

@ -30,11 +30,14 @@
////////////////////////////////////////////////////////////
#include <SFML/Graphics/RenderTextureImpl.hpp>
#include <SFML/Window/GlResource.hpp>
#include <SFML/Window/Context.hpp>
#include <memory>
namespace sf
{
class Context;
namespace priv
{
////////////////////////////////////////////////////////////
@ -113,7 +116,7 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
Context* m_context; //!< P-Buffer based context
std::unique_ptr<Context> m_context; //!< P-Buffer based context
unsigned int m_width; //!< Width of the P-Buffer
unsigned int m_height; //!< Height of the P-Buffer
};

View File

@ -28,12 +28,13 @@
#include <SFML/Graphics/RenderTextureImplFBO.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/System/Err.hpp>
#include <utility>
#include <mutex>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <mutex>
#include <utility>
namespace
@ -118,7 +119,7 @@ m_depthStencilBuffer(0),
m_colorBuffer (0),
m_width (0),
m_height (0),
m_context (nullptr),
m_context (),
m_textureId (0),
m_multisample (false),
m_stencil (false),
@ -169,9 +170,6 @@ RenderTextureImplFBO::~RenderTextureImplFBO()
// Clean up FBOs
destroyStaleFBOs();
// Delete the backup context if we had to create one
delete m_context;
}
@ -521,7 +519,7 @@ bool RenderTextureImplFBO::activate(bool active)
if (!contextId)
{
if (!m_context)
m_context = new Context;
m_context = std::make_unique<Context>();
if (!m_context->setActive(true))
{

View File

@ -29,13 +29,16 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/RenderTextureImpl.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/Window/GlResource.hpp>
#include <unordered_map>
#include <memory>
namespace sf
{
class Context;
namespace priv
{
////////////////////////////////////////////////////////////
@ -142,7 +145,7 @@ private:
unsigned int m_colorBuffer; //!< Optional multisample color buffer attached to the frame buffer
unsigned int m_width; //!< Width of the attachments
unsigned int m_height; //!< Height of the attachments
Context* m_context; //!< Backup OpenGL context, used when none already exist
std::unique_ptr<Context> m_context; //!< Backup OpenGL context, used when none already exist
unsigned int m_textureId; //!< The ID of the texture to attach to the FBO
bool m_multisample; //!< Whether we have to create a multisample frame buffer as well
bool m_stencil; //!< Whether we have stencil attachment

View File

@ -498,8 +498,7 @@ static void onLowMemory(ANativeActivity* activity)
JNIEXPORT void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize)
{
// Create an activity states (will keep us in the know, about events we care)
sf::priv::ActivityStates* states = nullptr;
states = new sf::priv::ActivityStates;
auto* states = new sf::priv::ActivityStates;
// Initialize the states value
states->activity = nullptr;

View File

@ -30,6 +30,7 @@
#include <SFML/Network/SocketImpl.hpp>
#include <SFML/System/Err.hpp>
#include <algorithm>
#include <memory>
#include <utility>
#ifdef _MSC_VER
@ -51,7 +52,7 @@ struct SocketSelector::SocketSelectorImpl
////////////////////////////////////////////////////////////
SocketSelector::SocketSelector() :
m_impl(new SocketSelectorImpl)
m_impl(std::make_unique<SocketSelectorImpl>())
{
clear();
}
@ -59,17 +60,14 @@ m_impl(new SocketSelectorImpl)
////////////////////////////////////////////////////////////
SocketSelector::SocketSelector(const SocketSelector& copy) :
m_impl(new SocketSelectorImpl(*copy.m_impl))
m_impl(std::make_unique<SocketSelectorImpl>(*copy.m_impl))
{
}
////////////////////////////////////////////////////////////
SocketSelector::~SocketSelector()
{
delete m_impl;
}
SocketSelector::~SocketSelector() = default;
////////////////////////////////////////////////////////////

View File

@ -29,7 +29,8 @@
#ifdef SFML_SYSTEM_ANDROID
#include <SFML/System/Android/ResourceStream.hpp>
#endif
#include <memory>
#include <cstddef>
namespace sf
{
@ -44,10 +45,7 @@ FileInputStream::FileInputStream()
////////////////////////////////////////////////////////////
FileInputStream::~FileInputStream()
{
#ifdef SFML_SYSTEM_ANDROID
if (m_file)
delete m_file;
#else
#ifndef SFML_SYSTEM_ANDROID
if (m_file)
std::fclose(m_file);
#endif
@ -58,9 +56,7 @@ FileInputStream::~FileInputStream()
bool FileInputStream::open(const std::string& filename)
{
#ifdef SFML_SYSTEM_ANDROID
if (m_file)
delete m_file;
m_file = new priv::ResourceStream(filename);
m_file = std::make_unique<priv::ResourceStream>(filename);
return m_file->tell() != -1;
#else
if (m_file)

View File

@ -60,8 +60,6 @@ Context::~Context()
{
err() << "Failed to set context as inactive during destruction" << std::endl;
}
delete m_context;
}
@ -90,7 +88,7 @@ const Context* Context::getActiveContext()
using ContextImpl::currentContext;
// We have to check that the last activated sf::Context is still active (a RenderTarget activation may have deactivated it)
if (currentContext && currentContext->m_context == priv::GlContext::getActiveContext())
if (currentContext && currentContext->m_context.get() == priv::GlContext::getActiveContext())
return currentContext;
else
return nullptr;

View File

@ -27,23 +27,22 @@
////////////////////////////////////////////////////////////
#include <SFML/Window/Cursor.hpp>
#include <SFML/Window/CursorImpl.hpp>
#include <SFML/System/Vector2.hpp>
#include <memory>
namespace sf
{
////////////////////////////////////////////////////////////
Cursor::Cursor() :
m_impl(new priv::CursorImpl())
m_impl(std::make_unique<priv::CursorImpl>())
{
// That's it
}
////////////////////////////////////////////////////////////
Cursor::~Cursor()
{
delete m_impl;
}
Cursor::~Cursor() = default;
////////////////////////////////////////////////////////////

View File

@ -131,7 +131,7 @@ m_config (nullptr)
////////////////////////////////////////////////////////////
EglContext::EglContext(EglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
EglContext::EglContext(EglContext* shared, const ContextSettings& settings, const WindowImpl& owner, unsigned int bitsPerPixel) :
m_display (EGL_NO_DISPLAY),
m_context (EGL_NO_CONTEXT),
m_surface (EGL_NO_SURFACE),
@ -162,7 +162,7 @@ m_config (nullptr)
#if !defined(SFML_SYSTEM_ANDROID)
// Create EGL surface (except on Android because the window is created
// asynchronously, its activity manager will call it for us)
createSurface(owner->getSystemHandle());
createSurface(owner.getSystemHandle());
#else
(void) owner;
#endif

View File

@ -63,7 +63,7 @@ public:
/// \param bitsPerPixel Pixel depth, in bits per pixel
///
////////////////////////////////////////////////////////////
EglContext(EglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
EglContext(EglContext* shared, const ContextSettings& settings, const WindowImpl& owner, unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target

View File

@ -31,16 +31,17 @@
#include <SFML/System/Err.hpp>
#include <glad/gl.h>
#include <algorithm>
#include <vector>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <cassert>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cassert>
#include <mutex>
#include <optional>
#if defined(SFML_SYSTEM_WINDOWS)
@ -166,7 +167,7 @@ namespace
thread_local sf::priv::GlContext* currentContext(nullptr);
// The hidden, inactive context that will be shared with all other contexts
ContextType* sharedContext = nullptr;
std::unique_ptr<ContextType> sharedContext;
// Unique identifier, used for identifying contexts when managing unshareable OpenGL resources
sf::Uint64 id = 1; // start at 1, zero is "no context"
@ -194,7 +195,7 @@ namespace
{
if (resourceCount == 0)
{
context = new sf::Context;
context = std::make_unique<sf::Context>();
}
else if (!currentContext)
{
@ -214,7 +215,7 @@ namespace
sharedContext->setActive(false);
sharedContextLock.reset();
delete context;
context.reset();
}
////////////////////////////////////////////////////////////
@ -233,14 +234,14 @@ namespace
// Member data
////////////////////////////////////////////////////////////
unsigned int referenceCount;
sf::Context* context;
std::unique_ptr<sf::Context> context;
std::optional<std::scoped_lock<std::recursive_mutex>> sharedContextLock;
bool useSharedContext;
};
// This per-thread variable tracks if and how a transient
// context is currently being used on the current thread
thread_local TransientContext* transientContext(nullptr);
thread_local std::unique_ptr<TransientContext> transientContext;
// Supported OpenGL extensions
std::vector<std::string> extensions;
@ -347,7 +348,7 @@ void GlContext::initResource()
}
// Create the shared context
sharedContext = new ContextType(nullptr);
sharedContext = std::make_unique<ContextType>(nullptr);
sharedContext->initialize(ContextSettings());
// Load our extensions vector
@ -382,8 +383,7 @@ void GlContext::cleanupResource()
return;
// Destroy the shared context
delete sharedContext;
sharedContext = nullptr;
sharedContext.reset();
}
}
@ -408,7 +408,7 @@ void GlContext::acquireTransientContext()
// If this is the first TransientContextLock on this thread
// construct the state object
if (!transientContext)
transientContext = new TransientContext;
transientContext = std::make_unique<TransientContext>();
// Increase the reference count
transientContext->referenceCount++;
@ -434,14 +434,13 @@ void GlContext::releaseTransientContext()
// destroy the state object
if (transientContext->referenceCount == 0)
{
delete transientContext;
transientContext = nullptr;
transientContext.reset();
}
}
////////////////////////////////////////////////////////////
GlContext* GlContext::create()
std::unique_ptr<GlContext> GlContext::create()
{
using GlContextImpl::mutex;
using GlContextImpl::sharedContext;
@ -451,7 +450,7 @@ GlContext* GlContext::create()
std::scoped_lock lock(mutex);
GlContext* context = nullptr;
std::unique_ptr<GlContext> context;
// We don't use acquireTransientContext here since we have
// to ensure we have exclusive access to the shared context
@ -460,7 +459,7 @@ GlContext* GlContext::create()
sharedContext->setActive(true);
// Create the context
context = new ContextType(sharedContext);
context = std::make_unique<ContextType>(sharedContext.get());
sharedContext->setActive(false);
}
@ -472,7 +471,7 @@ GlContext* GlContext::create()
////////////////////////////////////////////////////////////
GlContext* GlContext::create(const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel)
std::unique_ptr<GlContext> GlContext::create(const ContextSettings& settings, const WindowImpl& owner, unsigned int bitsPerPixel)
{
using GlContextImpl::mutex;
using GlContextImpl::resourceCount;
@ -495,15 +494,14 @@ GlContext* GlContext::create(const ContextSettings& settings, const WindowImpl*
// Re-create our shared context as a core context
ContextSettings sharedSettings(0, 0, 0, settings.majorVersion, settings.minorVersion, settings.attributeFlags);
delete sharedContext;
sharedContext = new ContextType(nullptr, sharedSettings, 1, 1);
sharedContext = std::make_unique<ContextType>(nullptr, sharedSettings, 1, 1);
sharedContext->initialize(sharedSettings);
// Reload our extensions vector
loadExtensions();
}
GlContext* context = nullptr;
std::unique_ptr<GlContext> context;
// We don't use acquireTransientContext here since we have
// to ensure we have exclusive access to the shared context
@ -512,7 +510,7 @@ GlContext* GlContext::create(const ContextSettings& settings, const WindowImpl*
sharedContext->setActive(true);
// Create the context
context = new ContextType(sharedContext, settings, owner, bitsPerPixel);
context = std::make_unique<ContextType>(sharedContext.get(), settings, owner, bitsPerPixel);
sharedContext->setActive(false);
}
@ -525,7 +523,7 @@ GlContext* GlContext::create(const ContextSettings& settings, const WindowImpl*
////////////////////////////////////////////////////////////
GlContext* GlContext::create(const ContextSettings& settings, unsigned int width, unsigned int height)
std::unique_ptr<GlContext> GlContext::create(const ContextSettings& settings, unsigned int width, unsigned int height)
{
using GlContextImpl::mutex;
using GlContextImpl::resourceCount;
@ -548,15 +546,14 @@ GlContext* GlContext::create(const ContextSettings& settings, unsigned int width
// Re-create our shared context as a core context
ContextSettings sharedSettings(0, 0, 0, settings.majorVersion, settings.minorVersion, settings.attributeFlags);
delete sharedContext;
sharedContext = new ContextType(nullptr, sharedSettings, 1, 1);
sharedContext = std::make_unique<ContextType>(nullptr, sharedSettings, 1, 1);
sharedContext->initialize(sharedSettings);
// Reload our extensions vector
loadExtensions();
}
GlContext* context = nullptr;
std::unique_ptr<GlContext> context;
// We don't use acquireTransientContext here since we have
// to ensure we have exclusive access to the shared context
@ -565,7 +562,7 @@ GlContext* GlContext::create(const ContextSettings& settings, unsigned int width
sharedContext->setActive(true);
// Create the context
context = new ContextType(sharedContext, settings, width, height);
context = std::make_unique<ContextType>(sharedContext.get(), settings, width, height);
sharedContext->setActive(false);
}

View File

@ -32,6 +32,7 @@
#include <SFML/Window/Context.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/Window/GlResource.hpp>
#include <memory>
namespace sf
@ -100,10 +101,10 @@ public:
/// This function automatically chooses the specialized class
/// to use according to the OS.
///
/// \return Pointer to the created context (don't forget to delete it)
/// \return Pointer to the created context
///
////////////////////////////////////////////////////////////
static GlContext* create();
static std::unique_ptr<GlContext> create();
////////////////////////////////////////////////////////////
/// \brief Create a new context attached to a window
@ -118,7 +119,7 @@ public:
/// \return Pointer to the created context
///
////////////////////////////////////////////////////////////
static GlContext* create(const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
static std::unique_ptr<GlContext> create(const ContextSettings& settings, const WindowImpl& owner, unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target
@ -133,7 +134,7 @@ public:
/// \return Pointer to the created context
///
////////////////////////////////////////////////////////////
static GlContext* create(const ContextSettings& settings, unsigned int width, unsigned int height);
static std::unique_ptr<GlContext> create(const ContextSettings& settings, unsigned int width, unsigned int height);
public:
////////////////////////////////////////////////////////////

View File

@ -83,7 +83,7 @@ public:
///
////////////////////////////////////////////////////////////
SFContext(SFContext* shared, const ContextSettings& settings,
const WindowImpl* owner, unsigned int bitsPerPixel);
const WindowImpl& owner, unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target

View File

@ -63,7 +63,7 @@ m_window(0)
////////////////////////////////////////////////////////////
SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
const WindowImpl* owner, unsigned int bitsPerPixel) :
const WindowImpl& owner, unsigned int bitsPerPixel) :
m_context(0),
m_view(0),
m_window(0)
@ -73,8 +73,8 @@ m_window(0)
createContext(shared, bitsPerPixel, settings);
// Apply context.
const WindowImplCocoa* ownerCocoa = static_cast<const WindowImplCocoa*>(owner);
ownerCocoa->applyContext(m_context);
const auto& ownerCocoa = static_cast<const WindowImplCocoa&>(owner);
ownerCocoa.applyContext(m_context);
}

View File

@ -131,7 +131,7 @@ m_ownsWindow(false)
////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int /*bitsPerPixel*/) :
GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl& owner, unsigned int /*bitsPerPixel*/) :
m_display (nullptr),
m_window (0),
m_context (nullptr),
@ -148,7 +148,7 @@ m_ownsWindow(false)
ensureExtensionsInit(m_display, DefaultScreen(m_display));
// Create the rendering surface from the owner window
createSurface(owner->getSystemHandle());
createSurface(owner.getSystemHandle());
// Create the context
createContext(shared);

View File

@ -62,7 +62,7 @@ public:
/// \param bitsPerPixel Pixel depth, in bits per pixel
///
////////////////////////////////////////////////////////////
GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl& owner, unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target

View File

@ -108,7 +108,7 @@ WglContext(shared, ContextSettings(), 1u, 1u)
////////////////////////////////////////////////////////////
WglContext::WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
WglContext::WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl& owner, unsigned int bitsPerPixel) :
m_window (nullptr),
m_pbuffer (nullptr),
m_deviceContext(nullptr),
@ -121,7 +121,7 @@ m_ownsWindow (false)
m_settings = settings;
// Create the rendering surface from the owner window
createSurface(owner->getSystemHandle(), bitsPerPixel);
createSurface(owner.getSystemHandle(), bitsPerPixel);
// Create the context
createContext(shared);

View File

@ -61,7 +61,7 @@ public:
/// \param bitsPerPixel Pixel depth, in bits per pixel
///
////////////////////////////////////////////////////////////
WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl& owner, unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target

View File

@ -36,7 +36,7 @@ namespace sf
{
////////////////////////////////////////////////////////////
Window::Window() :
m_context (nullptr),
m_context (),
m_frameTimeLimit(Time::Zero)
{
@ -45,7 +45,7 @@ m_frameTimeLimit(Time::Zero)
////////////////////////////////////////////////////////////
Window::Window(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings) :
m_context (nullptr),
m_context (),
m_frameTimeLimit(Time::Zero)
{
Window::create(mode, title, style, settings);
@ -54,7 +54,7 @@ m_frameTimeLimit(Time::Zero)
////////////////////////////////////////////////////////////
Window::Window(WindowHandle handle, const ContextSettings& settings) :
m_context (nullptr),
m_context (),
m_frameTimeLimit(Time::Zero)
{
Window::create(handle, settings);
@ -119,7 +119,7 @@ void Window::create(VideoMode mode, const String& title, Uint32 style, const Con
m_impl = priv::WindowImpl::create(mode, title, style, settings);
// Recreate the context
m_context = priv::GlContext::create(settings, m_impl, mode.bitsPerPixel);
m_context = priv::GlContext::create(settings, *m_impl, mode.bitsPerPixel);
// Perform common initializations
initialize();
@ -143,7 +143,7 @@ void Window::create(WindowHandle handle, const ContextSettings& settings)
WindowBase::create(handle);
// Recreate the context
m_context = priv::GlContext::create(settings, m_impl, VideoMode::getDesktopMode().bitsPerPixel);
m_context = priv::GlContext::create(settings, *m_impl, VideoMode::getDesktopMode().bitsPerPixel);
// Perform common initializations
initialize();
@ -154,8 +154,7 @@ void Window::create(WindowHandle handle, const ContextSettings& settings)
void Window::close()
{
// Delete the context
delete m_context;
m_context = nullptr;
m_context.reset();
// Close the base window
WindowBase::close();

View File

@ -45,8 +45,8 @@ namespace sf
{
////////////////////////////////////////////////////////////
WindowBase::WindowBase() :
m_impl (nullptr),
m_size (0, 0)
m_impl(),
m_size(0, 0)
{
}
@ -54,8 +54,8 @@ m_size (0, 0)
////////////////////////////////////////////////////////////
WindowBase::WindowBase(VideoMode mode, const String& title, Uint32 style) :
m_impl (nullptr),
m_size (0, 0)
m_impl(),
m_size(0, 0)
{
WindowBase::create(mode, title, style);
}
@ -63,8 +63,8 @@ m_size (0, 0)
////////////////////////////////////////////////////////////
WindowBase::WindowBase(WindowHandle handle) :
m_impl (nullptr),
m_size (0, 0)
m_impl(),
m_size(0, 0)
{
WindowBase::create(handle);
}
@ -143,8 +143,7 @@ void WindowBase::create(WindowHandle handle)
void WindowBase::close()
{
// Delete the window implementation
delete m_impl;
m_impl = nullptr;
m_impl.reset();
// Update the fullscreen window
if (this == getFullscreenWindow())

View File

@ -32,6 +32,7 @@
#include <SFML/Window/SensorManager.hpp>
#include <SFML/System/Sleep.hpp>
#include <algorithm>
#include <memory>
#include <cmath>
#if defined(SFML_SYSTEM_WINDOWS)
@ -85,22 +86,22 @@ struct WindowImpl::JoystickStatesImpl
};
////////////////////////////////////////////////////////////
WindowImpl* WindowImpl::create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings)
std::unique_ptr<WindowImpl> WindowImpl::create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings)
{
return new WindowImplType(mode, title, style, settings);
return std::make_unique<WindowImplType>(mode, title, style, settings);
}
////////////////////////////////////////////////////////////
WindowImpl* WindowImpl::create(WindowHandle handle)
std::unique_ptr<WindowImpl> WindowImpl::create(WindowHandle handle)
{
return new WindowImplType(handle);
return std::make_unique<WindowImplType>(handle);
}
////////////////////////////////////////////////////////////
WindowImpl::WindowImpl() :
m_joystickStatesImpl(new JoystickStatesImpl),
m_joystickStatesImpl(std::make_unique<JoystickStatesImpl>()),
m_joystickThreshold(0.1f)
{
// Get the initial joystick states
@ -118,10 +119,7 @@ m_joystickThreshold(0.1f)
////////////////////////////////////////////////////////////
WindowImpl::~WindowImpl()
{
delete m_joystickStatesImpl;
}
WindowImpl::~WindowImpl() = default;
////////////////////////////////////////////////////////////

View File

@ -38,6 +38,7 @@
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/Vulkan.hpp>
#include <SFML/Window/WindowHandle.hpp>
#include <memory>
#include <queue>
#include <set>
@ -64,20 +65,20 @@ public:
/// \param style Window style
/// \param settings Additional settings for the underlying OpenGL context
///
/// \return Pointer to the created window (don't forget to delete it)
/// \return Pointer to the created window
///
////////////////////////////////////////////////////////////
static WindowImpl* create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings);
static std::unique_ptr<WindowImpl> create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings);
////////////////////////////////////////////////////////////
/// \brief Create a new window depending on to the current OS
///
/// \param handle Platform-specific handle of the control
///
/// \return Pointer to the created window (don't forget to delete it)
/// \return Pointer to the created window
///
////////////////////////////////////////////////////////////
static WindowImpl* create(WindowHandle handle);
static std::unique_ptr<WindowImpl> create(WindowHandle handle);
public:
@ -294,7 +295,7 @@ private:
// Member data
////////////////////////////////////////////////////////////
std::queue<Event> m_events; //!< Queue of available events
JoystickStatesImpl* m_joystickStatesImpl; //!< Previous state of the joysticks (PImpl)
std::unique_ptr<JoystickStatesImpl> m_joystickStatesImpl; //!< Previous state of the joysticks (PImpl)
Vector3f m_sensorValue[Sensor::Count]; //!< Previous value of the sensors
float m_joystickThreshold; //!< Joystick threshold (minimum motion for "move" event to be generated)
float m_previousAxes[Joystick::Count][Joystick::AxisCount]; //!< Position of each axis last time a move event triggered, in range [-100, 100]

View File

@ -70,7 +70,7 @@ public:
///
////////////////////////////////////////////////////////////
EaglContext(EaglContext* shared, const ContextSettings& settings,
const WindowImpl* owner, unsigned int bitsPerPixel);
const WindowImpl& owner, unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target
@ -149,13 +149,13 @@ private:
/// \brief Create the context
///
/// \param shared Context to share the new one with (can be a null pointer)
/// \param window Window to attach the context to (can be a null pointer)
/// \param window Window to attach the context to
/// \param bitsPerPixel Pixel depth, in bits per pixel
/// \param settings Creation parameters
///
////////////////////////////////////////////////////////////
void createContext(EaglContext* shared,
const WindowImplUIKit* window,
const WindowImplUIKit& window,
unsigned int bitsPerPixel,
const ContextSettings& settings);

View File

@ -105,7 +105,7 @@ m_clock ()
////////////////////////////////////////////////////////////
EaglContext::EaglContext(EaglContext* shared, const ContextSettings& settings,
const WindowImpl* owner, unsigned int bitsPerPixel) :
const WindowImpl& owner, unsigned int bitsPerPixel) :
m_context (nil),
m_framebuffer (0),
m_colorbuffer (0),
@ -115,7 +115,7 @@ m_clock ()
{
ensureInit();
const WindowImplUIKit* window = static_cast<const WindowImplUIKit*>(owner);
const auto& window = static_cast<const WindowImplUIKit&>(owner);
createContext(shared, window, bitsPerPixel, settings);
}
@ -286,7 +286,7 @@ void EaglContext::setVerticalSyncEnabled(bool enabled)
////////////////////////////////////////////////////////////
void EaglContext::createContext(EaglContext* shared,
const WindowImplUIKit* window,
const WindowImplUIKit& window,
unsigned int /* bitsPerPixel */,
const ContextSettings& settings)
{
@ -318,10 +318,10 @@ void EaglContext::createContext(EaglContext* shared,
glGenFramebuffersOESFunc(1, &m_framebuffer);
// Create the render buffers
recreateRenderBuffers(window->getGlView());
recreateRenderBuffers(window.getGlView());
// Attach the context to the GL view for future updates
window->getGlView().context = this;
window.getGlView().context = this;
// Deactivate it
makeCurrent(false);