mirror of
https://github.com/SFML/SFML.git
synced 2024-11-24 20:31:05 +08:00
Use smart pointers to manage memory
This commit is contained in:
parent
257c78f07a
commit
f6de7eca40
@ -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;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio/Export.hpp>
|
||||
#include <SFML/System/Time.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
|
||||
@ -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<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?
|
||||
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<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
|
||||
unsigned int m_sampleRate; //!< Number of samples per second
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
@ -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
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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>(); }
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
#include <SFML/Window/ContextSettings.hpp>
|
||||
#include <memory>
|
||||
|
||||
|
||||
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<priv::RenderTextureImpl> m_impl; //!< Platform/hardware specific implementation
|
||||
Texture m_texture; //!< Target texture to draw on
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <SFML/Window/ContextSettings.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/Window/WindowBase.hpp>
|
||||
#include <memory>
|
||||
|
||||
|
||||
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<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
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <SFML/Window/WindowStyle.hpp>
|
||||
#include <SFML/System/Clock.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <memory>
|
||||
|
||||
|
||||
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<priv::WindowImpl> m_impl; //!< Platform-specific implementation of the window
|
||||
Vector2u m_size; //!< Current size of the window
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,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<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
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -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:
|
||||
|
||||
@ -293,11 +294,11 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
std::queue<Event> 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<Event> m_events; //!< Queue of available events
|
||||
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]
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user