Stopping a Queued instance
chungwong opened this issue · 0 comments
chungwong commented
Currently a Quened instance handle cannot be stopped.
This is an example of the scenario using the main branch with commit [63d4f82] instead of v0.10.
trait Channel = Sync + Send + Resource;
pub(crate) struct ChannelState<T> {
pub(crate) handle: Option<Handle<AudioSource>>,
pub(crate) instance_handle: Option<InstanceHandle>,
_marker: PhantomData<T>,
}
impl<T> Default for ChannelState<T> {
fn default() -> Self {
Self {
handle: None,
instance_handle: None,
_marker: PhantomData,
}
}
}
#[derive(Component, Debug, Default, Clone)]
pub(crate) struct MusicChannel;
pub struct AudioPlugin;
impl Plugin for AudioPlugin {
fn build(&self, app: &mut App) {
app.add_plugin(KiraAudioPlugin)
.insert_resource(ChannelState::<MusicChannel>::default())
.add_audio_channel::<MusicChannel>()
.add_enter_system(GameState::MainMenu, play_menu_music)
.add_enter_system(GameState::InGame, play_game_music)
.add_system(play_channel::<MusicChannel>)
.add_system(print_status::<MusicChannel>)
;
}
}
fn print_status<T: Channel>(
audio: Res<AudioChannel<T>>,
channel_state: Res<ChannelState<T>>,
) {
if let Some(instance_handle) = &channel_state.instance_handle {
let state = audio.state(instance_handle.clone());
println!("Loop audio {:?} {:?}", state, instance_handle);
}
}
#[allow(clippy::only_used_in_recursion)]
fn play_menu_music(
mut channel_state: ResMut<ChannelState<MusicChannel>>,
asset_server: Res<AssetServer>,
audio: Res<AudioChannel<MusicChannel>>,
) {
dbg!("play main menu music");
channel_state.handle = Some(asset_server.load("music/TownTheme.mp3"));
}
#[allow(clippy::only_used_in_recursion)]
fn play_game_music(
mut channel_state: ResMut<ChannelState<MusicChannel>>,
asset_server: Res<AssetServer>,
audio: Res<AudioChannel<MusicChannel>>,
) {
audio.stop();
dbg!("play another music");
}
fn play_channel<T: Channel>(
mut channel_state: ResMut<ChannelState<T>>,
audio: Res<AudioChannel<T>>,
) {
if let ChannelState {
handle: Some(handle),
..
} = &*channel_state
{
channel_state.instance_handle = Some(audio.play(handle.clone()));
channel_state.handle = None;
}
}
- At first,
MusicChannel
is added. - At game state
MainMenu
,play_menu_music
is to load the mp3 file, it took seconds to load it and it is in the state ofQueued
- While the instance is still
Queued
, the game state changed toInGame
and there is a new music to be played byplay_game_music
. - Even though
audio.stop()
is issued, the instance won't be stopped. - Once the instance is ready, it will play in
InGame
.
So although there is audio.stop()
when the channel is switched over to the new one, now both MainMenu
music and the InGame
music play together.