playdate icon indicating copy to clipboard operation
playdate copied to clipboard

Rustify this function, maybe impl like it done for sprites.

Open github-actions[bot] opened this issue 9 months ago • 0 comments

Rustify this function, maybe impl like it done for sprites. https://api.github.com/boozook/playdate/blob/e4c7b9442cf7637a812c52fbeee32d49cbaacba7/api/sound/src/player/sp/mod.rs#L200

My idea is to store user-callback into self,

and here use proxy "extern C" function.

Maybe move self into the wrapper with user-callback?

We're need so store user-callback somewhere like StackedMap(stacked_type_map) or ErasedSet by type.

Type of `F: FnMut(*mut SoundSource)` is unique, so we can do it.

But with cost of memory - one static for each `F`*`Self`, so so much.

Source of this issue


// impl //

impl<Api> Player<Api> where Api: api::Api {
	/// Assigns `sample` to player.
	///
	/// Equivalent to [setSample](sys::ffi::playdate_sound_sampleplayer::setSample)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::setSample")]
	pub fn set_sample(&self, sample: &crate::sample::Sample) {
		let f = self.api().set_sample();
		unsafe { f(self.0, sample.0) }
	}


	/// Returns `true` if player is playing a sample, `false` if not.
	///
	/// Equivalent to [isPlaying](sys::ffi::playdate_sound_sampleplayer::isPlaying)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::isPlaying")]
	pub fn is_playing(&self) -> bool {
		let f = self.api().is_playing();
		unsafe { f(self.0) == 1 }
	}


	/// Starts playing the sample in player.
	/// Sets the playback rate for the sample. 1.0 is normal speed, 0.5 is down an octave, 2.0 is up an octave, etc.
	///
	/// Equivalent to [play](sys::ffi::playdate_sound_sampleplayer::play)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::play")]
	pub fn play(&self, repeat: Repeat, rate: c_float) -> c_int {
		let f = self.api().play();
		unsafe { f(self.0, repeat.into(), rate) }
	}

	/// Stops playing the sample.
	///
	/// Equivalent to [stop](sys::ffi::playdate_sound_sampleplayer::stop)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::stop")]
	pub fn stop(&self) {
		let f = self.api().stop();
		unsafe { f(self.0) }
	}


	/// Gets the current left and right channel volume of the player.
	///
	/// Equivalent to [getVolume](sys::ffi::playdate_sound_sampleplayer::getVolume)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::getVolume")]
	pub fn volume(&self) -> (c_float, c_float) {
		let (mut left, mut right) = (0.0, 0.0);
		let f = self.api().get_volume();
		unsafe { f(self.0, &mut left, &mut right) };
		(left, right)
	}

	/// Sets the playback volume for left and right channels.
	///
	/// Equivalent to [setVolume](sys::ffi::playdate_sound_sampleplayer::setVolume)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::setVolume")]
	pub fn set_volume(&self, left: c_float, right: c_float) {
		let f = self.api().set_volume();
		unsafe { f(self.0, left, right) }
	}

	/// Returns the length, in seconds, of the sample assigned to player.
	///
	/// Equivalent to [getLength](sys::ffi::playdate_sound_sampleplayer::getLength)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::getLength")]
	pub fn length(&self) -> c_float {
		let f = self.api().get_length();
		unsafe { f(self.0) }
	}

	/// Gets the current offset in seconds for player.
	///
	/// Equivalent to [getOffset](sys::ffi::playdate_sound_sampleplayer::getOffset)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::getOffset")]
	pub fn offset(&self) -> c_float {
		let f = self.api().get_offset();
		unsafe { f(self.0) }
	}

	/// Sets the current offset of the player, in seconds.
	///
	/// Equivalent to [setOffset](sys::ffi::playdate_sound_sampleplayer::setOffset)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::setOffset")]
	pub fn set_offset(&self, offset: c_float) {
		let f = self.api().set_offset();
		unsafe { f(self.0, offset) }
	}

	/// Gets the playback rate for player.
	///
	/// Equivalent to [getRate](sys::ffi::playdate_sound_sampleplayer::getRate)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::getRate")]
	pub fn rate(&self) -> c_float {
		let f = self.api().get_rate();
		unsafe { f(self.0) }
	}

	/// Sets the playback rate for the player. 1.0 is normal speed, 0.5 is down an octave, 2.0 is up an octave, etc. A negative rate produces backwards playback for PCM files, but does not work for ADPCM-encoded files.
	///
	/// Equivalent to [setRate](sys::ffi::playdate_sound_sampleplayer::setRate)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::setRate")]
	pub fn set_rate(&self, rate: c_float) {
		let f = self.api().set_rate();
		unsafe { f(self.0, rate) }
	}

	/// When used with a [`Repeat::PingPong`], does ping-pong looping, with a `start` and `end` position in frames.
	///
	/// Equivalent to [setPlayRange](sys::ffi::playdate_sound_sampleplayer::setPlayRange)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::setPlayRange")]
	pub fn set_play_range(&self, start: c_int, end: c_int) {
		let f = self.api().set_play_range();
		unsafe { f(self.0, start, end) }
	}

	/// Pauses or resumes playback.
	///
	/// Equivalent to [setPaused](sys::ffi::playdate_sound_sampleplayer::setPaused)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::setPaused")]
	pub fn set_paused(&self, value: bool) {
		let f = self.api().set_paused();
		unsafe { f(self.0, value as _) }
	}


	// callbacks //

	/// Sets a function to be called when playback has completed.
	///
	/// Equivalent to [setFinishCallback](sys::ffi::playdate_sound_sampleplayer::setFinishCallback)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::setFinishCallback")]
	// TODO: Rustify this function, maybe impl like it done for sprites.
	// My idea is to store user-callback into self,
	// and here use proxy "extern C" function.
	// Maybe move self into the wrapper with user-callback?
	// We're need so store user-callback somewhere like StackedMap(stacked_type_map) or ErasedSet by type.
	// Type of `F: FnMut(*mut SoundSource)` is unique, so we can do it.
	// But with cost of memory - one static for each `F`*`Self`, so so much.
	pub fn set_finish_callback_raw(&self, callback: sndCallbackProc) -> Result<(), Error> {
		let f = self.api().set_finish_callback();
		Ok(unsafe { f(self.0, callback) })
	}

	/// Equivalent to [setLoopCallback](sys::ffi::playdate_sound_sampleplayer::setLoopCallback)
	#[doc(alias = "sys::ffi::playdate_sound_sampleplayer::setLoopCallback")]
	pub fn set_loop_callback_raw(&self, callback: sndCallbackProc) -> Result<(), Error> {
		let f = self.api().set_loop_callback();
		Ok(unsafe { f(self.0, callback) })
	}
}

github-actions[bot] avatar Sep 28 '23 13:09 github-actions[bot]