Simplify/optimize sf::AudioResource implementation

This commit is contained in:
Vittorio Romeo 2024-06-20 01:07:01 +02:00 committed by Lukas Dürrenberger
parent 14cff7406f
commit cede2def8b
2 changed files with 51 additions and 29 deletions

View File

@ -29,8 +29,6 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Audio/Export.hpp> #include <SFML/Audio/Export.hpp>
#include <memory>
namespace sf namespace sf
{ {
@ -45,7 +43,7 @@ public:
/// \brief Copy constructor /// \brief Copy constructor
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
AudioResource(const AudioResource&) = default; AudioResource(const AudioResource&);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Copy assignment /// \brief Copy assignment
@ -57,7 +55,7 @@ public:
/// \brief Move constructor /// \brief Move constructor
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
AudioResource(AudioResource&&) noexcept = default; AudioResource(AudioResource&&) noexcept;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Move assignment /// \brief Move assignment
@ -65,25 +63,25 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
AudioResource& operator=(AudioResource&&) noexcept = default; AudioResource& operator=(AudioResource&&) noexcept = default;
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~AudioResource();
protected: protected:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Default constructor /// \brief Default constructor
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
AudioResource(); AudioResource();
private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::shared_ptr<void> m_device; //!< Sound device
}; };
} // namespace sf } // namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::AlResource /// \class sf::AudioResource
/// \ingroup audio /// \ingroup audio
/// ///
/// This class is for internal use only, it must be the base /// This class is for internal use only, it must be the base

View File

@ -28,34 +28,58 @@
#include <SFML/Audio/AudioDevice.hpp> #include <SFML/Audio/AudioDevice.hpp>
#include <SFML/Audio/AudioResource.hpp> #include <SFML/Audio/AudioResource.hpp>
#include <memory>
#include <mutex> #include <mutex>
#include <optional>
namespace
{
////////////////////////////////////////////////////////////
struct DeviceState
{
std::mutex mutex;
std::optional<sf::priv::AudioDevice> device;
unsigned int referenceCounter{};
};
////////////////////////////////////////////////////////////
DeviceState& getDeviceState()
{
static DeviceState deviceState;
return deviceState;
}
} // namespace
namespace sf namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
AudioResource::AudioResource() : AudioResource::AudioResource()
m_device( {
[] auto& [mutex, device, referenceCounter] = getDeviceState();
{ const std::lock_guard guard{mutex};
// Ensure we only ever create a single instance of an
// AudioDevice that is shared between all AudioResources
static std::mutex mutex;
static std::weak_ptr<priv::AudioDevice> weakAudioDevice;
const std::lock_guard lock(mutex); if (referenceCounter++ == 0u)
device.emplace();
}
auto audioDevice = weakAudioDevice.lock(); ////////////////////////////////////////////////////////////
AudioResource::~AudioResource()
{
auto& [mutex, device, referenceCounter] = getDeviceState();
const std::lock_guard guard{mutex};
if (audioDevice == nullptr) if (--referenceCounter == 0u)
{ device.reset();
audioDevice = std::make_shared<priv::AudioDevice>(); }
weakAudioDevice = audioDevice;
}
return audioDevice; ////////////////////////////////////////////////////////////
}()) AudioResource::AudioResource(const AudioResource&) : AudioResource{}
{
}
////////////////////////////////////////////////////////////
AudioResource::AudioResource(AudioResource&&) noexcept : AudioResource{}
{ {
} }