diff --git a/include/SFML/Audio/AudioResource.hpp b/include/SFML/Audio/AudioResource.hpp index 6e68d0762..323063749 100644 --- a/include/SFML/Audio/AudioResource.hpp +++ b/include/SFML/Audio/AudioResource.hpp @@ -29,6 +29,8 @@ //////////////////////////////////////////////////////////// #include +#include + namespace sf { @@ -43,7 +45,7 @@ public: /// \brief Copy constructor /// //////////////////////////////////////////////////////////// - AudioResource(const AudioResource&); + AudioResource(const AudioResource&) = default; //////////////////////////////////////////////////////////// /// \brief Copy assignment @@ -55,7 +57,7 @@ public: /// \brief Move constructor /// //////////////////////////////////////////////////////////// - AudioResource(AudioResource&&) noexcept; + AudioResource(AudioResource&&) noexcept = default; //////////////////////////////////////////////////////////// /// \brief Move assignment @@ -63,18 +65,18 @@ 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 diff --git a/src/SFML/Audio/AudioResource.cpp b/src/SFML/Audio/AudioResource.cpp index 01829c9ac..1d476f2ee 100644 --- a/src/SFML/Audio/AudioResource.cpp +++ b/src/SFML/Audio/AudioResource.cpp @@ -28,58 +28,34 @@ #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() -{ - auto& [mutex, device, referenceCounter] = getDeviceState(); - const std::lock_guard guard{mutex}; +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; - if (referenceCounter++ == 0u) - device.emplace(); -} + const std::lock_guard lock(mutex); -//////////////////////////////////////////////////////////// -AudioResource::~AudioResource() -{ - auto& [mutex, device, referenceCounter] = getDeviceState(); - const std::lock_guard guard{mutex}; + auto audioDevice = weakAudioDevice.lock(); - if (--referenceCounter == 0u) - device.reset(); -} + if (audioDevice == nullptr) + { + audioDevice = std::make_shared(); + weakAudioDevice = audioDevice; + } -//////////////////////////////////////////////////////////// -AudioResource::AudioResource(const AudioResource&) : AudioResource{} -{ -} - -//////////////////////////////////////////////////////////// -AudioResource::AudioResource(AudioResource&&) noexcept : AudioResource{} + return audioDevice; + }()) { }