diff --git a/SDL2pp/AudioDevice.hh b/SDL2pp/AudioDevice.hh index 7d87f3d..eedbe86 100644 --- a/SDL2pp/AudioDevice.hh +++ b/SDL2pp/AudioDevice.hh @@ -35,21 +35,96 @@ class AudioSpec; class AudioDevice { public: + //////////////////////////////////////////////////////////// + /// \brief SDL2pp::AudioDevice lock + /// \ingroup audio + /// + /// \details + /// Audio devices may be locked, which means that audio + /// callback will not be called in a locked state, allowing + /// to change data it accesses in a thread-safe way. + /// + /// This class represents the lock and controls its lifetime + /// as the lock is released as soon as LockHandle is destroyed. + /// + /// Usage example: + /// \code + /// { + /// // Some audio data is loaded + /// SDL2pp::Wav audiodata; + /// + /// // Audio device is created, its callback accesses our audio data + /// SDL2pp::AudioDevice dev(..., [&audiodata](){...}); + /// + /// dev.Pause(false); // playback starts, the callback is called periodically + /// + /// { + /// SDL2pp::AudioDevice::LockHandle lock = dev.Lock(); + /// // Now audiodata may be safely modified, no callback will be called to access it + /// } + /// // At this point lock is released, playback continues + /// } + /// \endcode + /// + //////////////////////////////////////////////////////////// class LockHandle { friend class AudioDevice; private: - AudioDevice* device_; + AudioDevice* device_; ///< SDL2pp::AudioDevice the lock belongs to private: + //////////////////////////////////////////////////////////// + /// \brief Create lock for specific SDL2pp::AudioDevice + /// + /// \param device Pointer to audio device to lock + /// + /// \see http://wiki.libsdl.org/SDL_LockAudioDevice + /// + /// This operation locks a device, which remains locked + /// until LockHandle is destroyed + /// + /// Recursive locking is allowed + /// + //////////////////////////////////////////////////////////// LockHandle(AudioDevice* device); public: + //////////////////////////////////////////////////////////// + /// \brief Create no-op lock + /// + /// \details + /// This may be initialized with real lock later with move + /// assignment operator + /// + //////////////////////////////////////////////////////////// LockHandle(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// \details + /// Releases the lock + /// + //////////////////////////////////////////////////////////// ~LockHandle(); + //////////////////////////////////////////////////////////// + /// \brief Move constructor + /// + /// \param other SDL2pp::AudioDevice::LockHandle to move data from + /// + //////////////////////////////////////////////////////////// LockHandle(LockHandle&& other) noexcept; + + //////////////////////////////////////////////////////////// + /// \brief Move assignment operator + /// + /// \param other SDL2pp::AudioDevice::LockHandle to move data from + /// + //////////////////////////////////////////////////////////// LockHandle& operator=(LockHandle&& other) noexcept; + // Deleted copy constructor and assignment LockHandle(const LockHandle& other) = delete; LockHandle& operator=(const LockHandle& other) = delete; }; @@ -57,8 +132,8 @@ public: typedef std::function AudioCallback; private: - SDL_AudioDeviceID device_id_; - AudioCallback callback_; + SDL_AudioDeviceID device_id_; ///< SDL2 device id + AudioCallback callback_; ///< Callback used to feed audio data to the device private: static void SDLCallback(void *userdata, Uint8* stream, int len); @@ -80,6 +155,19 @@ public: void ChangeCallback(AudioCallback&& callback); + //////////////////////////////////////////////////////////// + /// \brief Lock audio device to prevent it from calling audio callback + /// + /// \returns Lock handle used to control lock lifetime + /// + /// \details + /// The device remains locked for the lifetime of returned LockHandle + /// + /// Recursive locking is allowed + // + /// \see http://wiki.libsdl.org/SDL_LockAudioDevice + /// + //////////////////////////////////////////////////////////// LockHandle Lock(); #ifdef SDL2PP_WITH_2_0_4 diff --git a/SDL2pp/Texture.hh b/SDL2pp/Texture.hh index dea0ef8..5a915fa 100644 --- a/SDL2pp/Texture.hh +++ b/SDL2pp/Texture.hh @@ -49,27 +49,114 @@ private: SDL_Texture* texture_; ///< SDL2 texture pointer public: + //////////////////////////////////////////////////////////// + /// \brief SDL2pp::Texture lock + /// \ingroup rendering + /// + /// \details + /// Textures with SDL_TEXTUREACCESS_STREAMING access mode may + /// be locked, which provides (writeonly) access to their raw + /// pixel data. This may be used to update texture contents. + /// + /// This class represents the lock and controls its lifetime + /// as the lock is released as soon as LockHandle is destroyed. + /// + /// Usage example: + /// \code + /// { + /// SDL2pp::Texture tex(SDL_PIXELFORMAT_RGB24, + /// SDL_TEXTUREACCESS_STREAMING, + /// 256, 256); + /// { + /// // Lock the whole texture + /// SDL2pp::Texture::LockHandle lock = tex.Lock(); + /// + /// unsigned char* start = static_cast(lock.GetPixels()); + /// + /// // note that we use lock.GetPitch(), not tex.GetWidth() here + /// // as texture may have different dimensions in memory + /// unsigned char* end = start + tex.GetHeight() * lock.GetPitch(); + /// + /// // fill the texture white + /// std::fill(start, end, 255); + /// } + /// // At this point lock is released + /// } + /// \endcode + /// + //////////////////////////////////////////////////////////// class LockHandle { friend class Texture; private: - Texture* texture_; - void* pixels_; - int pitch_; + Texture* texture_; ///< SDL2pp::Texture this lock belongs to + void* pixels_; ///< Pointer to raw pixel data of locked region + int pitch_; ///< Pitch (row length) of pixel data in bytes private: + //////////////////////////////////////////////////////////// + /// \brief Create lock for specific SDL2pp::Texture + /// + /// \param rect Specifies region to lock + /// + /// \see http://wiki.libsdl.org/SDL_LockAudioDevice + /// + //////////////////////////////////////////////////////////// LockHandle(Texture* texture, const Rect& rect); public: + //////////////////////////////////////////////////////////// + /// \brief Create no-op lock + /// + /// \details + /// This may be initialized with real lock later with move + /// assignment operator + /// + //////////////////////////////////////////////////////////// LockHandle(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// \details + /// Releases the lock + /// + //////////////////////////////////////////////////////////// ~LockHandle(); + //////////////////////////////////////////////////////////// + /// \brief Move constructor + /// + /// \param other SDL2pp::AudioDevice::LockHandle to move data from + /// + //////////////////////////////////////////////////////////// LockHandle(LockHandle&& other) noexcept; + + //////////////////////////////////////////////////////////// + /// \brief Move assignment operator + /// + /// \param other SDL2pp::AudioDevice::LockHandle to move data from + /// + //////////////////////////////////////////////////////////// LockHandle& operator=(LockHandle&& other) noexcept; + // Deleted copy constructor and assignment LockHandle(const LockHandle& other) = delete; LockHandle& operator=(const LockHandle& other) = delete; + //////////////////////////////////////////////////////////// + /// \brief Get pointer to raw pixel data of locked region + /// + /// \returns Pointer to raw pixel data of locked region + /// + //////////////////////////////////////////////////////////// void* GetPixels() const; + + //////////////////////////////////////////////////////////// + /// \brief Get row width of locked pixel data + /// + /// \returns Pitch (row width) of locked pixel data + /// + //////////////////////////////////////////////////////////// int GetPitch() const; }; @@ -100,7 +187,7 @@ public: /// \param rect Rect representing area to lock for access /// (Rect::Null() to lock entire texture) /// - /// \return Lock handle used to access pixel data and to control lifetime of the lock + /// \return Lock handle used to access pixel data and to control lock lifetime /// //////////////////////////////////////////////////////////// LockHandle Lock(const Rect& rect);