diff --git a/include/SFML/Audio/AudioResource.hpp b/include/SFML/Audio/AudioResource.hpp index cfb4dca29..6e68d0762 100644 --- a/include/SFML/Audio/AudioResource.hpp +++ b/include/SFML/Audio/AudioResource.hpp @@ -29,8 +29,6 @@ //////////////////////////////////////////////////////////// #include -#include - namespace sf { @@ -45,7 +43,7 @@ public: /// \brief Copy constructor /// //////////////////////////////////////////////////////////// - AudioResource(const AudioResource&) = default; + AudioResource(const AudioResource&); //////////////////////////////////////////////////////////// /// \brief Copy assignment @@ -57,7 +55,7 @@ public: /// \brief Move constructor /// //////////////////////////////////////////////////////////// - AudioResource(AudioResource&&) noexcept = default; + AudioResource(AudioResource&&) noexcept; //////////////////////////////////////////////////////////// /// \brief Move assignment @@ -65,25 +63,25 @@ public: //////////////////////////////////////////////////////////// AudioResource& operator=(AudioResource&&) noexcept = default; + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + //////////////////////////////////////////////////////////// + ~AudioResource(); + protected: //////////////////////////////////////////////////////////// /// \brief Default constructor /// //////////////////////////////////////////////////////////// AudioResource(); - -private: - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - std::shared_ptr m_device; //!< Sound device }; } // namespace sf //////////////////////////////////////////////////////////// -/// \class sf::AlResource +/// \class sf::AudioResource /// \ingroup audio /// /// This class is for internal use only, it must be the base diff --git a/src/SFML/Audio/AudioResource.cpp b/src/SFML/Audio/AudioResource.cpp index 1d476f2ee..01829c9ac 100644 --- a/src/SFML/Audio/AudioResource.cpp +++ b/src/SFML/Audio/AudioResource.cpp @@ -28,34 +28,58 @@ #include #include -#include #include +#include +namespace +{ +//////////////////////////////////////////////////////////// +struct DeviceState +{ + std::mutex mutex; + std::optional device; + unsigned int referenceCounter{}; +}; + +//////////////////////////////////////////////////////////// +DeviceState& getDeviceState() +{ + static DeviceState deviceState; + return deviceState; +} + +} // namespace + namespace sf { //////////////////////////////////////////////////////////// -AudioResource::AudioResource() : -m_device( - [] - { - // 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 weakAudioDevice; +AudioResource::AudioResource() +{ + auto& [mutex, device, referenceCounter] = getDeviceState(); + const std::lock_guard guard{mutex}; - 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) - { - audioDevice = std::make_shared(); - weakAudioDevice = audioDevice; - } + if (--referenceCounter == 0u) + device.reset(); +} - return audioDevice; - }()) +//////////////////////////////////////////////////////////// +AudioResource::AudioResource(const AudioResource&) : AudioResource{} +{ +} + +//////////////////////////////////////////////////////////// +AudioResource::AudioResource(AudioResource&&) noexcept : AudioResource{} { }