Skip to content

Commit a3b503b

Browse files
committed
Changing the default PlaybackMode to PlaybackMode::Remove
Adding `PlaybackMode` to `AudioPlayer` Adding convience methods to `AudioPlayer` to create with different `PlaybackMode`s
1 parent 56d5591 commit a3b503b

File tree

10 files changed

+51
-58
lines changed

10 files changed

+51
-58
lines changed

crates/bevy_audio/src/audio.rs

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl Volume {
3333
}
3434

3535
/// The way Bevy manages the sound playback.
36-
#[derive(Debug, Clone, Copy, Reflect)]
36+
#[derive(Debug, Clone, Copy, Reflect, Default)]
3737
pub enum PlaybackMode {
3838
/// Play the sound once. Do nothing when it ends.
3939
Once,
@@ -42,6 +42,7 @@ pub enum PlaybackMode {
4242
/// Despawn the entity and its children when the sound finishes playing.
4343
Despawn,
4444
/// Remove the audio components from the entity, when the sound finishes playing.
45+
#[default]
4546
Remove,
4647
}
4748

@@ -53,8 +54,6 @@ pub enum PlaybackMode {
5354
#[derive(Component, Clone, Copy, Debug, Reflect)]
5455
#[reflect(Default, Component, Debug)]
5556
pub struct PlaybackSettings {
56-
/// The desired playback behavior.
57-
pub mode: PlaybackMode,
5857
/// Volume to play at.
5958
pub volume: Volume,
6059
/// Speed to play at.
@@ -77,40 +76,17 @@ pub struct PlaybackSettings {
7776

7877
impl Default for PlaybackSettings {
7978
fn default() -> Self {
80-
// TODO: what should the default be: ONCE/DESPAWN/REMOVE?
81-
Self::ONCE
79+
Self {
80+
volume: Volume(1.0),
81+
speed: 1.0,
82+
paused: false,
83+
spatial: false,
84+
spatial_scale: None,
85+
}
8286
}
8387
}
8488

8589
impl PlaybackSettings {
86-
/// Will play the associated audio source once.
87-
pub const ONCE: PlaybackSettings = PlaybackSettings {
88-
mode: PlaybackMode::Once,
89-
volume: Volume(1.0),
90-
speed: 1.0,
91-
paused: false,
92-
spatial: false,
93-
spatial_scale: None,
94-
};
95-
96-
/// Will play the associated audio source in a loop.
97-
pub const LOOP: PlaybackSettings = PlaybackSettings {
98-
mode: PlaybackMode::Loop,
99-
..PlaybackSettings::ONCE
100-
};
101-
102-
/// Will play the associated audio source once and despawn the entity afterwards.
103-
pub const DESPAWN: PlaybackSettings = PlaybackSettings {
104-
mode: PlaybackMode::Despawn,
105-
..PlaybackSettings::ONCE
106-
};
107-
108-
/// Will play the associated audio source once and remove the audio components afterwards.
109-
pub const REMOVE: PlaybackSettings = PlaybackSettings {
110-
mode: PlaybackMode::Remove,
111-
..PlaybackSettings::ONCE
112-
};
113-
11490
/// Helper to start in a paused state.
11591
pub const fn paused(mut self) -> Self {
11692
self.paused = true;
@@ -251,7 +227,7 @@ pub type AudioBundle = AudioSourceBundle<AudioSource>;
251227
#[derive(Component, Reflect)]
252228
#[reflect(Component)]
253229
#[require(PlaybackSettings)]
254-
pub struct AudioPlayer<Source = AudioSource>(pub Handle<Source>)
230+
pub struct AudioPlayer<Source = AudioSource>(pub Handle<Source>, pub PlaybackMode)
255231
where
256232
Source: Asset + Decodable;
257233

@@ -260,7 +236,7 @@ where
260236
Source: Asset + Decodable,
261237
{
262238
fn clone(&self) -> Self {
263-
Self(self.0.clone())
239+
Self(self.0.clone(), self.1.clone())
264240
}
265241
}
266242

@@ -271,7 +247,27 @@ impl AudioPlayer<AudioSource> {
271247
/// initialize an [`AudioPlayer`] with a different type, just initialize it directly using normal
272248
/// tuple struct syntax.
273249
pub fn new(source: Handle<AudioSource>) -> Self {
274-
Self(source)
250+
Self(source, PlaybackMode::default())
251+
}
252+
253+
/// Creates a new [`AudioPlayer`] that plays the sound once.
254+
pub fn with_once(source: Handle<AudioSource>) -> Self {
255+
Self(source, PlaybackMode::Once)
256+
}
257+
258+
/// Creates a new [`AudioPlayer`] that loops the sound forever.
259+
pub fn with_loop(source: Handle<AudioSource>) -> Self {
260+
Self(source, PlaybackMode::Loop)
261+
}
262+
263+
/// Creates a new [`AudioPlayer`] that despawns the entity when the sound finishes playing.
264+
pub fn with_despawn(source: Handle<AudioSource>) -> Self {
265+
Self(source, PlaybackMode::Despawn)
266+
}
267+
268+
/// Creates a new [`AudioPlayer`] that removes the audio component from the entity when the sound finishes playing.
269+
pub fn with_remove(source: Handle<AudioSource>) -> Self {
270+
Self(source, PlaybackMode::Remove)
275271
}
276272
}
277273

@@ -314,7 +310,7 @@ impl<T: Asset + Decodable> Clone for AudioSourceBundle<T> {
314310
impl<T: Decodable + Asset> Default for AudioSourceBundle<T> {
315311
fn default() -> Self {
316312
Self {
317-
source: AudioPlayer(Handle::default()),
313+
source: AudioPlayer(Handle::default(), PlaybackMode::Once),
318314
settings: Default::default(),
319315
}
320316
}

crates/bevy_audio/src/audio_output.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
164164
sink.pause();
165165
}
166166

167-
match settings.mode {
167+
match source_handle.1 {
168168
PlaybackMode::Loop => {
169169
sink.append(audio_source.decoder().repeat_infinite());
170170
commands.entity(entity).insert(SpatialAudioSink { sink });
@@ -204,7 +204,7 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
204204
sink.pause();
205205
}
206206

207-
match settings.mode {
207+
match source_handle.1 {
208208
PlaybackMode::Loop => {
209209
sink.append(audio_source.decoder().repeat_infinite());
210210
commands.entity(entity).insert(AudioSink { sink });

examples/audio/audio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn main() {
1111
}
1212

1313
fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
14-
commands.spawn(AudioPlayer::new(
14+
commands.spawn(AudioPlayer::with_once(
1515
asset_server.load("sounds/Windless Slopes.ogg"),
1616
));
1717
}

examples/audio/decodable.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Shows how to create a custom [`Decodable`] type by implementing a Sine wave.
22
33
use bevy::{
4-
audio::{AddAudioSource, AudioPlugin, Source},
4+
audio::{AddAudioSource, AudioPlugin, PlaybackMode, Source},
55
math::ops,
66
prelude::*,
77
reflect::TypePath,
@@ -99,5 +99,5 @@ fn setup(mut assets: ResMut<Assets<SineAudio>>, mut commands: Commands) {
9999
let audio_handle = assets.add(SineAudio {
100100
frequency: 440., // this is the frequency of A4
101101
});
102-
commands.spawn(AudioPlayer(audio_handle));
102+
commands.spawn(AudioPlayer(audio_handle, PlaybackMode::Once));
103103
}

examples/audio/pitch.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This example illustrates how to play a single-frequency sound (aka a pitch)
22
3-
use bevy::prelude::*;
3+
use bevy::{audio::PlaybackMode, prelude::*};
44
use std::time::Duration;
55

66
fn main() {
@@ -30,9 +30,9 @@ fn play_pitch(
3030
) {
3131
for _ in events.read() {
3232
info!("playing pitch with frequency: {}", frequency.0);
33-
commands.spawn((
34-
AudioPlayer(pitch_assets.add(Pitch::new(frequency.0, Duration::new(1, 0)))),
35-
PlaybackSettings::DESPAWN,
33+
commands.spawn(AudioPlayer(
34+
pitch_assets.add(Pitch::new(frequency.0, Duration::new(1, 0))),
35+
PlaybackMode::Despawn,
3636
));
3737
info!("number of pitch assets: {}", pitch_assets.len());
3838
}

examples/audio/soundtrack.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,8 @@ fn change_track(
7979
match game_state.as_ref() {
8080
GameState::Peaceful => {
8181
commands.spawn((
82-
AudioPlayer(soundtrack_player.track_list.first().unwrap().clone()),
82+
AudioPlayer::with_loop(soundtrack_player.track_list.first().unwrap().clone()),
8383
PlaybackSettings {
84-
mode: bevy::audio::PlaybackMode::Loop,
8584
volume: bevy::audio::Volume::ZERO,
8685
..default()
8786
},
@@ -90,9 +89,8 @@ fn change_track(
9089
}
9190
GameState::Battle => {
9291
commands.spawn((
93-
AudioPlayer(soundtrack_player.track_list.get(1).unwrap().clone()),
92+
AudioPlayer::with_loop(soundtrack_player.track_list.get(1).unwrap().clone()),
9493
PlaybackSettings {
95-
mode: bevy::audio::PlaybackMode::Loop,
9694
volume: bevy::audio::Volume::ZERO,
9795
..default()
9896
},

examples/audio/spatial_audio_2d.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ fn setup(
3838
MeshMaterial2d(materials.add(Color::from(BLUE))),
3939
Transform::from_translation(Vec3::new(0.0, 50.0, 0.0)),
4040
Emitter::default(),
41-
AudioPlayer::new(asset_server.load("sounds/Windless Slopes.ogg")),
42-
PlaybackSettings::LOOP.with_spatial(true),
41+
AudioPlayer::with_loop(asset_server.load("sounds/Windless Slopes.ogg")),
42+
PlaybackSettings::default().with_spatial(true),
4343
));
4444

4545
let listener = SpatialListener::new(gap);

examples/audio/spatial_audio_3d.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ fn setup(
2929
MeshMaterial3d(materials.add(Color::from(BLUE))),
3030
Transform::from_xyz(0.0, 0.0, 0.0),
3131
Emitter::default(),
32-
AudioPlayer::new(asset_server.load("sounds/Windless Slopes.ogg")),
33-
PlaybackSettings::LOOP.with_spatial(true),
32+
AudioPlayer::with_loop(asset_server.load("sounds/Windless Slopes.ogg")),
33+
PlaybackSettings::default().with_spatial(true),
3434
));
3535

3636
let listener = SpatialListener::new(gap);

examples/games/breakout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ fn play_collision_sound(
404404
if !collision_events.is_empty() {
405405
// This prevents events staying active on the next frame.
406406
collision_events.clear();
407-
commands.spawn((AudioPlayer(sound.clone()), PlaybackSettings::DESPAWN));
407+
commands.spawn(AudioPlayer::with_despawn(sound.clone()));
408408
}
409409
}
410410

examples/mobile/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,8 @@ fn button_handler(
165165
}
166166

167167
fn setup_music(asset_server: Res<AssetServer>, mut commands: Commands) {
168-
commands.spawn((
169-
AudioPlayer::new(asset_server.load("sounds/Windless Slopes.ogg")),
170-
PlaybackSettings::LOOP,
168+
commands.spawn(AudioPlayer::with_loop(
169+
asset_server.load("sounds/Windless Slopes.ogg"),
171170
));
172171
}
173172

0 commit comments

Comments
 (0)