diff --git a/examples/shader/Shader.cpp b/examples/shader/Shader.cpp index 828ad23f0..bf9837888 100644 --- a/examples/shader/Shader.cpp +++ b/examples/shader/Shader.cpp @@ -3,7 +3,7 @@ // Headers //////////////////////////////////////////////////////////// #include "Effect.hpp" -#include +#include #include @@ -357,12 +357,20 @@ int main() Effect::setFont(font); // Create the effects - std::vector 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 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; } diff --git a/include/SFML/Audio/InputSoundFile.hpp b/include/SFML/Audio/InputSoundFile.hpp index 156f5e23d..f010258eb 100644 --- a/include/SFML/Audio/InputSoundFile.hpp +++ b/include/SFML/Audio/InputSoundFile.hpp @@ -30,6 +30,7 @@ //////////////////////////////////////////////////////////// #include #include +#include #include #include @@ -218,17 +219,32 @@ 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 + template + StreamDeleter(const std::default_delete&); + + 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? - 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 - unsigned int m_sampleRate; //!< Number of samples per second + std::unique_ptr m_reader; //!< Reader that handles I/O on the file's format + std::unique_ptr 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 + unsigned int m_sampleRate; //!< Number of samples per second }; } // namespace sf diff --git a/include/SFML/Audio/OutputSoundFile.hpp b/include/SFML/Audio/OutputSoundFile.hpp index 97be0ffb0..f31067d2d 100644 --- a/include/SFML/Audio/OutputSoundFile.hpp +++ b/include/SFML/Audio/OutputSoundFile.hpp @@ -29,6 +29,7 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #include @@ -104,7 +105,7 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - SoundFileWriter* m_writer; //!< Writer that handles I/O on the file's format + std::unique_ptr m_writer; //!< Writer that handles I/O on the file's format }; } // namespace sf diff --git a/include/SFML/Audio/SoundFileFactory.hpp b/include/SFML/Audio/SoundFileFactory.hpp index 654cac1fb..6614f10f4 100644 --- a/include/SFML/Audio/SoundFileFactory.hpp +++ b/include/SFML/Audio/SoundFileFactory.hpp @@ -29,6 +29,7 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #include #include @@ -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 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 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 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 createWriterFromFilename(const std::string& filename); private: @@ -146,14 +139,14 @@ private: struct ReaderFactory { bool (*check)(InputStream&); - SoundFileReader* (*create)(); + std::unique_ptr (*create)(); }; using ReaderFactoryArray = std::vector; struct WriterFactory { bool (*check)(const std::string&); - SoundFileWriter* (*create)(); + std::unique_ptr (*create)(); }; using WriterFactoryArray = std::vector; diff --git a/include/SFML/Audio/SoundFileFactory.inl b/include/SFML/Audio/SoundFileFactory.inl index 9ca571b34..d573c605f 100644 --- a/include/SFML/Audio/SoundFileFactory.inl +++ b/include/SFML/Audio/SoundFileFactory.inl @@ -31,8 +31,8 @@ namespace sf { namespace priv { - template SoundFileReader* createReader() {return new T;} - template SoundFileWriter* createWriter() {return new T;} + template std::unique_ptr createReader() { return std::make_unique(); } + template std::unique_ptr createWriter() { return std::make_unique(); } } //////////////////////////////////////////////////////////// diff --git a/include/SFML/Graphics/Font.hpp b/include/SFML/Graphics/Font.hpp index 2d377e6e1..58b81b61c 100644 --- a/include/SFML/Graphics/Font.hpp +++ b/include/SFML/Graphics/Font.hpp @@ -32,11 +32,19 @@ #include #include #include -#include +#include #include +#include #include +#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; //!< 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 - 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 m_pixelBuffer; //!< Pixel buffer holding a glyph's pixels before being written to the texture + std::shared_ptr 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 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 m_stream; //!< Asset file streamer (if loaded from file) #endif }; diff --git a/include/SFML/Graphics/RenderTexture.hpp b/include/SFML/Graphics/RenderTexture.hpp index 3f5717284..120fde171 100644 --- a/include/SFML/Graphics/RenderTexture.hpp +++ b/include/SFML/Graphics/RenderTexture.hpp @@ -32,6 +32,7 @@ #include #include #include +#include namespace sf @@ -228,8 +229,8 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - priv::RenderTextureImpl* m_impl; //!< Platform/hardware specific implementation - Texture m_texture; //!< Target texture to draw on + std::unique_ptr m_impl; //!< Platform/hardware specific implementation + Texture m_texture; //!< Target texture to draw on }; } // namespace sf diff --git a/include/SFML/Network/SocketSelector.hpp b/include/SFML/Network/SocketSelector.hpp index 16a49af64..45c31941e 100644 --- a/include/SFML/Network/SocketSelector.hpp +++ b/include/SFML/Network/SocketSelector.hpp @@ -30,6 +30,7 @@ //////////////////////////////////////////////////////////// #include #include +#include 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 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 clients; +/// std::list> 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(); /// 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 diff --git a/include/SFML/System/FileInputStream.hpp b/include/SFML/System/FileInputStream.hpp index 91e22771b..806665ab3 100644 --- a/include/SFML/System/FileInputStream.hpp +++ b/include/SFML/System/FileInputStream.hpp @@ -31,8 +31,9 @@ #include #include #include -#include +#include #include +#include #ifdef SFML_SYSTEM_ANDROID namespace sf @@ -134,7 +135,7 @@ private: // Member data //////////////////////////////////////////////////////////// #ifdef SFML_SYSTEM_ANDROID - priv::ResourceStream* m_file; + std::unique_ptr m_file; #else std::FILE* m_file; //!< stdio file stream #endif diff --git a/include/SFML/Window/Context.hpp b/include/SFML/Window/Context.hpp index 0fb5d82b0..73f1fb869 100644 --- a/include/SFML/Window/Context.hpp +++ b/include/SFML/Window/Context.hpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace sf @@ -161,7 +162,7 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - priv::GlContext* m_context; //!< Internal OpenGL context + std::unique_ptr m_context; //!< Internal OpenGL context }; } // namespace sf diff --git a/include/SFML/Window/Cursor.hpp b/include/SFML/Window/Cursor.hpp index 7d728b23a..e0fc1a13f 100644 --- a/include/SFML/Window/Cursor.hpp +++ b/include/SFML/Window/Cursor.hpp @@ -30,6 +30,7 @@ //////////////////////////////////////////////////////////// #include #include +#include namespace sf { @@ -209,7 +210,7 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - priv::CursorImpl* m_impl; //!< Platform-specific implementation of the cursor + std::unique_ptr m_impl; //!< Platform-specific implementation of the cursor }; } // namespace sf diff --git a/include/SFML/Window/Window.hpp b/include/SFML/Window/Window.hpp index bdc5a358f..d29442e19 100644 --- a/include/SFML/Window/Window.hpp +++ b/include/SFML/Window/Window.hpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace sf @@ -276,9 +277,9 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - 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 + std::unique_ptr 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 }; } // namespace sf diff --git a/include/SFML/Window/WindowBase.hpp b/include/SFML/Window/WindowBase.hpp index 9702537a9..46d55c251 100644 --- a/include/SFML/Window/WindowBase.hpp +++ b/include/SFML/Window/WindowBase.hpp @@ -36,6 +36,7 @@ #include #include #include +#include namespace sf @@ -482,8 +483,8 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - priv::WindowImpl* m_impl; //!< Platform-specific implementation of the window - Vector2u m_size; //!< Current size of the window + std::unique_ptr m_impl; //!< Platform-specific implementation of the window + Vector2u m_size; //!< Current size of the window }; } // namespace sf diff --git a/src/SFML/Audio/AlResource.cpp b/src/SFML/Audio/AlResource.cpp index 973b1f0b2..9664c435b 100644 --- a/src/SFML/Audio/AlResource.cpp +++ b/src/SFML/Audio/AlResource.cpp @@ -27,6 +27,7 @@ //////////////////////////////////////////////////////////// #include #include +#include #include @@ -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 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(); // 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 diff --git a/src/SFML/Audio/InputSoundFile.cpp b/src/SFML/Audio/InputSoundFile.cpp index d55d26be4..7d17ad310 100644 --- a/src/SFML/Audio/InputSoundFile.cpp +++ b/src/SFML/Audio/InputSoundFile.cpp @@ -38,12 +38,35 @@ namespace sf { +//////////////////////////////////////////////////////////// +InputSoundFile::StreamDeleter::StreamDeleter(bool theOwned) : owned{theOwned} +{ + +} + + +//////////////////////////////////////////////////////////// +template +InputSoundFile::StreamDeleter::StreamDeleter(const std::default_delete&) +: owned{true} +{ + +} + + +//////////////////////////////////////////////////////////// +void InputSoundFile::StreamDeleter::operator()(InputStream* ptr) const +{ + if (owned) + std::default_delete{}(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(); // 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(); // 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; diff --git a/src/SFML/Audio/OutputSoundFile.cpp b/src/SFML/Audio/OutputSoundFile.cpp index 6771b0efe..1dccf4c2a 100644 --- a/src/SFML/Audio/OutputSoundFile.cpp +++ b/src/SFML/Audio/OutputSoundFile.cpp @@ -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 diff --git a/src/SFML/Audio/SoundFileFactory.cpp b/src/SFML/Audio/SoundFileFactory.cpp index a3328fca8..2151afbd9 100644 --- a/src/SFML/Audio/SoundFileFactory.cpp +++ b/src/SFML/Audio/SoundFileFactory.cpp @@ -65,7 +65,7 @@ SoundFileFactory::WriterFactoryArray SoundFileFactory::s_writers; //////////////////////////////////////////////////////////// -SoundFileReader* SoundFileFactory::createReaderFromFilename(const std::string& filename) +std::unique_ptr 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 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 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 SoundFileFactory::createWriterFromFilename(const std::string& filename) { // Register the built-in readers/writers on first call ensureDefaultReadersWritersRegistered(); diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index 6a9831f55..92592d2d8 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -38,6 +38,7 @@ #include FT_OUTLINE_H #include FT_BITMAP_H #include FT_STROKER_H +#include #include #include #include @@ -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, Deleter> library; //< Pointer to the internal library interface + std::unique_ptr streamRec; //< Pointer to the stream rec instance + std::unique_ptr, Deleter> face; //< Pointer to the internal font face + std::unique_ptr, 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(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(); // 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(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(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(m_stream); - - m_stream = new priv::ResourceStream(filename); - return loadFromStream(*static_cast(m_stream)); + m_stream = std::make_unique(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(); // 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(m_library), reinterpret_cast(data), static_cast(sizeInBytes), 0, &face) != 0) + if (FT_New_Memory_Face(library, reinterpret_cast(data), static_cast(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(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(); // 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(stream.getSize()); - rec->pos = 0; - rec->descriptor.pointer = &stream; - rec->read = &read; - rec->close = &close; + font->streamRec = std::make_unique(); + std::memset(font->streamRec.get(), 0, sizeof(*font->streamRec)); + font->streamRec->base = nullptr; + font->streamRec->size = static_cast(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(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(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(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(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(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(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(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(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(m_stroker)); - - // Destroy the font face - if (m_face) - FT_Done_Face(static_cast(m_face)); - - // Destroy the stream rec instance, if any (must be done after FT_Done_Face!) - if (m_streamRec) - delete static_cast(m_streamRec); - - // Close the library - if (m_library) - FT_Done_FreeType(static_cast(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().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(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(m_stroker); + auto stroker = m_font->stroker.get(); FT_Stroker_Set(stroker, static_cast(outlineThickness * static_cast(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(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(m_face); + auto face = m_font->face.get(); FT_UShort currentSize = face->size->metrics.x_ppem; if (currentSize != characterSize) diff --git a/src/SFML/Graphics/RenderTexture.cpp b/src/SFML/Graphics/RenderTexture.cpp index e894e320c..ee060ded1 100644 --- a/src/SFML/Graphics/RenderTexture.cpp +++ b/src/SFML/Graphics/RenderTexture.cpp @@ -29,23 +29,17 @@ #include #include #include +#include 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(); // 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(); } // Initialize the render texture diff --git a/src/SFML/Graphics/RenderTextureImplDefault.cpp b/src/SFML/Graphics/RenderTextureImplDefault.cpp index 41844c970..8880427cb 100644 --- a/src/SFML/Graphics/RenderTextureImplDefault.cpp +++ b/src/SFML/Graphics/RenderTextureImplDefault.cpp @@ -29,6 +29,7 @@ #include #include #include +#include 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(settings, width, height); return true; } diff --git a/src/SFML/Graphics/RenderTextureImplDefault.hpp b/src/SFML/Graphics/RenderTextureImplDefault.hpp index b79ce0b66..30c93478b 100644 --- a/src/SFML/Graphics/RenderTextureImplDefault.hpp +++ b/src/SFML/Graphics/RenderTextureImplDefault.hpp @@ -30,11 +30,14 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include namespace sf { +class Context; + + namespace priv { //////////////////////////////////////////////////////////// @@ -113,9 +116,9 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - 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 + std::unique_ptr m_context; //!< P-Buffer based context + unsigned int m_width; //!< Width of the P-Buffer + unsigned int m_height; //!< Height of the P-Buffer }; } // namespace priv diff --git a/src/SFML/Graphics/RenderTextureImplFBO.cpp b/src/SFML/Graphics/RenderTextureImplFBO.cpp index 3705519da..88af5b005 100644 --- a/src/SFML/Graphics/RenderTextureImplFBO.cpp +++ b/src/SFML/Graphics/RenderTextureImplFBO.cpp @@ -28,12 +28,13 @@ #include #include #include +#include #include -#include +#include +#include #include #include -#include -#include +#include 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(); if (!m_context->setActive(true)) { diff --git a/src/SFML/Graphics/RenderTextureImplFBO.hpp b/src/SFML/Graphics/RenderTextureImplFBO.hpp index 0b2fc70f3..1569d274c 100644 --- a/src/SFML/Graphics/RenderTextureImplFBO.hpp +++ b/src/SFML/Graphics/RenderTextureImplFBO.hpp @@ -29,13 +29,16 @@ // Headers //////////////////////////////////////////////////////////// #include -#include #include #include +#include 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 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 diff --git a/src/SFML/Main/MainAndroid.cpp b/src/SFML/Main/MainAndroid.cpp index 010fca855..2aaa56da9 100644 --- a/src/SFML/Main/MainAndroid.cpp +++ b/src/SFML/Main/MainAndroid.cpp @@ -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; diff --git a/src/SFML/Network/SocketSelector.cpp b/src/SFML/Network/SocketSelector.cpp index a4b9a1e23..c7c5b003a 100644 --- a/src/SFML/Network/SocketSelector.cpp +++ b/src/SFML/Network/SocketSelector.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #ifdef _MSC_VER @@ -51,7 +52,7 @@ struct SocketSelector::SocketSelectorImpl //////////////////////////////////////////////////////////// SocketSelector::SocketSelector() : -m_impl(new SocketSelectorImpl) +m_impl(std::make_unique()) { 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(*copy.m_impl)) { } //////////////////////////////////////////////////////////// -SocketSelector::~SocketSelector() -{ - delete m_impl; -} +SocketSelector::~SocketSelector() = default; //////////////////////////////////////////////////////////// diff --git a/src/SFML/System/FileInputStream.cpp b/src/SFML/System/FileInputStream.cpp index d5b184b33..73316f350 100644 --- a/src/SFML/System/FileInputStream.cpp +++ b/src/SFML/System/FileInputStream.cpp @@ -29,7 +29,8 @@ #ifdef SFML_SYSTEM_ANDROID #include #endif - +#include +#include 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(filename); return m_file->tell() != -1; #else if (m_file) diff --git a/src/SFML/Window/Context.cpp b/src/SFML/Window/Context.cpp index e7a891393..eb600cb11 100644 --- a/src/SFML/Window/Context.cpp +++ b/src/SFML/Window/Context.cpp @@ -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; diff --git a/src/SFML/Window/Cursor.cpp b/src/SFML/Window/Cursor.cpp index ee8fb627a..08c4a6a3a 100644 --- a/src/SFML/Window/Cursor.cpp +++ b/src/SFML/Window/Cursor.cpp @@ -27,23 +27,22 @@ //////////////////////////////////////////////////////////// #include #include +#include +#include namespace sf { //////////////////////////////////////////////////////////// Cursor::Cursor() : -m_impl(new priv::CursorImpl()) +m_impl(std::make_unique()) { - // That's it + } //////////////////////////////////////////////////////////// -Cursor::~Cursor() -{ - delete m_impl; -} +Cursor::~Cursor() = default; //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/EglContext.cpp b/src/SFML/Window/EglContext.cpp index dc46e6f68..1741c84e5 100644 --- a/src/SFML/Window/EglContext.cpp +++ b/src/SFML/Window/EglContext.cpp @@ -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 diff --git a/src/SFML/Window/EglContext.hpp b/src/SFML/Window/EglContext.hpp index f88ce7986..7858b4ce7 100644 --- a/src/SFML/Window/EglContext.hpp +++ b/src/SFML/Window/EglContext.hpp @@ -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 diff --git a/src/SFML/Window/GlContext.cpp b/src/SFML/Window/GlContext.cpp index 73c8a700f..41b9ed7de 100644 --- a/src/SFML/Window/GlContext.cpp +++ b/src/SFML/Window/GlContext.cpp @@ -31,16 +31,17 @@ #include #include #include -#include +#include +#include +#include #include #include #include +#include +#include +#include #include #include -#include -#include -#include -#include #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 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(); } 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 context; std::optional> 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; // Supported OpenGL extensions std::vector extensions; @@ -347,7 +348,7 @@ void GlContext::initResource() } // Create the shared context - sharedContext = new ContextType(nullptr); + sharedContext = std::make_unique(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(); // 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::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 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(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::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(nullptr, sharedSettings, 1, 1); sharedContext->initialize(sharedSettings); // Reload our extensions vector loadExtensions(); } - GlContext* context = nullptr; + std::unique_ptr 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(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::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(nullptr, sharedSettings, 1, 1); sharedContext->initialize(sharedSettings); // Reload our extensions vector loadExtensions(); } - GlContext* context = nullptr; + std::unique_ptr 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(sharedContext.get(), settings, width, height); sharedContext->setActive(false); } diff --git a/src/SFML/Window/GlContext.hpp b/src/SFML/Window/GlContext.hpp index 20dad919a..49b689f1e 100644 --- a/src/SFML/Window/GlContext.hpp +++ b/src/SFML/Window/GlContext.hpp @@ -32,6 +32,7 @@ #include #include #include +#include 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 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 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 create(const ContextSettings& settings, unsigned int width, unsigned int height); public: //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/OSX/SFContext.hpp b/src/SFML/Window/OSX/SFContext.hpp index 3aa19b372..a004a3a09 100644 --- a/src/SFML/Window/OSX/SFContext.hpp +++ b/src/SFML/Window/OSX/SFContext.hpp @@ -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 diff --git a/src/SFML/Window/OSX/SFContext.mm b/src/SFML/Window/OSX/SFContext.mm index 2195b5913..72e67a192 100644 --- a/src/SFML/Window/OSX/SFContext.mm +++ b/src/SFML/Window/OSX/SFContext.mm @@ -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(owner); - ownerCocoa->applyContext(m_context); + const auto& ownerCocoa = static_cast(owner); + ownerCocoa.applyContext(m_context); } diff --git a/src/SFML/Window/Unix/GlxContext.cpp b/src/SFML/Window/Unix/GlxContext.cpp index aa548c947..ec3d32638 100644 --- a/src/SFML/Window/Unix/GlxContext.cpp +++ b/src/SFML/Window/Unix/GlxContext.cpp @@ -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); diff --git a/src/SFML/Window/Unix/GlxContext.hpp b/src/SFML/Window/Unix/GlxContext.hpp index e5a990364..6ebd7182b 100644 --- a/src/SFML/Window/Unix/GlxContext.hpp +++ b/src/SFML/Window/Unix/GlxContext.hpp @@ -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 diff --git a/src/SFML/Window/Win32/WglContext.cpp b/src/SFML/Window/Win32/WglContext.cpp index 8f673fcbb..4777ad31c 100644 --- a/src/SFML/Window/Win32/WglContext.cpp +++ b/src/SFML/Window/Win32/WglContext.cpp @@ -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); diff --git a/src/SFML/Window/Win32/WglContext.hpp b/src/SFML/Window/Win32/WglContext.hpp index db600a4e1..8757ce20d 100644 --- a/src/SFML/Window/Win32/WglContext.hpp +++ b/src/SFML/Window/Win32/WglContext.hpp @@ -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 diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp index f0a5247ff..e4013e48a 100644 --- a/src/SFML/Window/Window.cpp +++ b/src/SFML/Window/Window.cpp @@ -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(); diff --git a/src/SFML/Window/WindowBase.cpp b/src/SFML/Window/WindowBase.cpp index 159ff19ff..ca0c9e8d1 100644 --- a/src/SFML/Window/WindowBase.cpp +++ b/src/SFML/Window/WindowBase.cpp @@ -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()) diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp index 4b83a815b..af8aa5e4f 100644 --- a/src/SFML/Window/WindowImpl.cpp +++ b/src/SFML/Window/WindowImpl.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #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::create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings) { - return new WindowImplType(mode, title, style, settings); + return std::make_unique(mode, title, style, settings); } //////////////////////////////////////////////////////////// -WindowImpl* WindowImpl::create(WindowHandle handle) +std::unique_ptr WindowImpl::create(WindowHandle handle) { - return new WindowImplType(handle); + return std::make_unique(handle); } //////////////////////////////////////////////////////////// WindowImpl::WindowImpl() : -m_joystickStatesImpl(new JoystickStatesImpl), +m_joystickStatesImpl(std::make_unique()), 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; //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp index 469dfe530..cfc786196 100644 --- a/src/SFML/Window/WindowImpl.hpp +++ b/src/SFML/Window/WindowImpl.hpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -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 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 create(WindowHandle handle); public: @@ -293,11 +294,11 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - std::queue m_events; //!< Queue of available events - 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] + std::queue m_events; //!< Queue of available events + std::unique_ptr 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] }; } // namespace priv diff --git a/src/SFML/Window/iOS/EaglContext.hpp b/src/SFML/Window/iOS/EaglContext.hpp index 346f682b0..7144cf3af 100644 --- a/src/SFML/Window/iOS/EaglContext.hpp +++ b/src/SFML/Window/iOS/EaglContext.hpp @@ -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); diff --git a/src/SFML/Window/iOS/EaglContext.mm b/src/SFML/Window/iOS/EaglContext.mm index eec33e72b..042074517 100644 --- a/src/SFML/Window/iOS/EaglContext.mm +++ b/src/SFML/Window/iOS/EaglContext.mm @@ -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(owner); + const auto& window = static_cast(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);