From 18181ce5a8032416149c68a166c46cf46f2757de Mon Sep 17 00:00:00 2001
From: Louis Capitanchik <contact@louiscap.co>
Date: Mon, 6 Feb 2023 13:29:59 +0000
Subject: [PATCH] Don't restart track if it matches current track

---
 Cargo.toml       |  8 ++++----
 src/music_box.rs | 40 +++++++++++++++++++++++++++++++++++++---
 2 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 29a251e..9e0aeb9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "micro_musicbox"
-version = "0.5.0"
+version = "0.5.1"
 edition = "2021"
 license = "Apache-2.0"
 authors = ["Louis Capitanchik <louis@microhacks.co.uk>"]
@@ -19,10 +19,10 @@ wav = ["bevy_kira_audio/wav"]
 ogg = ["bevy_kira_audio/ogg"]
 
 [dependencies]
-bevy = { version = "0.9.0", default-features = false }
+bevy = { version = "0.9.1", default-features = false }
 bevy_kira_audio = { version = "0.13.0", default-features = false }
 serde = { version = "1", optional = true }
 
 [dev_dependencies]
-bevy = "0.9.0"
-log = "0.4"
\ No newline at end of file
+bevy = "0.9.1"
+log = "0.4"
diff --git a/src/music_box.rs b/src/music_box.rs
index 36be07f..95bc4ca 100644
--- a/src/music_box.rs
+++ b/src/music_box.rs
@@ -39,7 +39,11 @@ pub struct MusicBox<'w, 's, T: SuppliesAudio> {
 #[derive(Debug, Default, Resource)]
 pub struct MusicBoxState {
 	pub active_music: Option<Handle<AudioInstance>>,
+	/// The name used to start the currently active music track
+	pub active_music_name: Option<String>,
 	pub active_ambiance: Option<Handle<AudioInstance>>,
+	/// The name used to start the currently active ambiance track
+	pub active_ambiance_name: Option<String>,
 }
 
 impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
@@ -54,6 +58,10 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		name: Name,
 		fade: AudioTween,
 	) -> Option<Handle<AudioInstance>> {
+		if self.state.active_music_name == Some(name.to_string()) {
+			return self.state.active_music.as_ref().map(|f| f.clone_weak());
+		}
+
 		self.fade_out_music(fade.clone());
 		self.fade_in_music(name, fade)
 	}
@@ -71,6 +79,10 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		in_tween: AudioTween,
 		out_tween: AudioTween,
 	) -> Option<Handle<AudioInstance>> {
+		if self.state.active_music_name == Some(name.to_string()) {
+			return self.state.active_music.as_ref().map(|f| f.clone_weak());
+		}
+
 		self.fade_out_music(out_tween);
 		self.fade_in_music(name, in_tween)
 	}
@@ -82,6 +94,10 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 	///
 	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn play_music<Name: ToString>(&mut self, name: Name) -> Option<Handle<AudioInstance>> {
+		if self.state.active_music_name == Some(name.to_string()) {
+			return self.state.active_music.as_ref().map(|f| f.clone_weak());
+		}
+
 		self.stop_music();
 		self.fade_in_music(name, AudioTween::default())
 	}
@@ -94,8 +110,14 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 	/// Stop playing music on the music channel. The supplied tween will be used to fade out the track
 	/// before it ends
 	pub fn fade_out_music(&mut self, fade: AudioTween) {
-		let handle = std::mem::replace(&mut self.state.active_music, None)
+		self.state.active_music_name = None;
+
+		let handle = self
+			.state
+			.active_music
+			.take()
 			.and_then(|handle| self.audio_instances.get_mut(&handle));
+
 		if let Some(current) = handle {
 			current.stop(fade);
 		}
@@ -112,7 +134,13 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		name: Name,
 		fade: AudioTween,
 	) -> Option<Handle<AudioInstance>> {
-		match self.map_tracks(name) {
+		let name = name.to_string();
+
+		if self.state.active_music_name.as_ref() == Some(&name) {
+			return self.state.active_music.as_ref().map(|f| f.clone_weak());
+		}
+
+		match self.map_tracks(&name) {
 			TrackType::WithIntro(_, track) | TrackType::Single(track) => {
 				let next = self
 					.channels
@@ -121,6 +149,8 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 					.fade_in(fade)
 					.looped()
 					.handle();
+
+				self.state.active_music_name = Some(name.clone());
 				self.state.active_music = Some(next.clone());
 
 				Some(next)
@@ -180,8 +210,12 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 	/// Stop playing ambiance on the ambiance channel. The supplied tween will be used to fade out the track
 	/// before it ends
 	pub fn fade_out_ambiance(&mut self, fade: AudioTween) {
-		let handle = std::mem::replace(&mut self.state.active_ambiance, None)
+		let handle = self
+			.state
+			.active_ambiance
+			.take()
 			.and_then(|handle| self.audio_instances.get_mut(&handle));
+
 		if let Some(current) = handle {
 			current.stop(fade);
 		}
-- 
GitLab