From 4b12b35026a92151850775b865613f0c8bf3f850 Mon Sep 17 00:00:00 2001 From: harshsomankar123-tech Date: Fri, 10 Apr 2026 15:31:13 +0530 Subject: [PATCH 1/4] CATROID-1554: Refactor WaitForSoundAction to Kotlin --- .../content/actions/WaitForSoundAction.java | 97 ----------------- .../content/actions/WaitForSoundAction.kt | 102 ++++++++++++++++++ 2 files changed, 102 insertions(+), 97 deletions(-) delete mode 100644 catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.java create mode 100644 catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt diff --git a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.java b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.java deleted file mode 100644 index f5b221bd7e6..00000000000 --- a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Catroid: An on-device visual programming system for Android devices - * Copyright (C) 2010-2025 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * An additional term exception under section 7 of the GNU Affero - * General Public License, version 3, is available at - * http://developer.catrobat.org/license_additional_term - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.catroid.content.actions; - -import org.catrobat.catroid.content.MediaPlayerWithSoundDetails; -import org.catrobat.catroid.content.SoundFilePathWithSprite; -import org.catrobat.catroid.io.SoundManager; -import org.catrobat.catroid.pocketmusic.mididriver.MidiPlayer; -import org.catrobat.catroid.pocketmusic.mididriver.MidiSoundManager; - -import java.util.Set; - -import androidx.annotation.VisibleForTesting; - -public class WaitForSoundAction extends WaitAction { - public static final String TAG = WaitForSoundAction.class.getSimpleName(); - private String soundFilePath; - private SoundManager soundManager = SoundManager.getInstance(); - private MidiSoundManager midiSoundManager = MidiSoundManager.getInstance(); - private boolean soundStopped = false; - - public void setSoundFilePath(String soundFilePath) { - this.soundFilePath = soundFilePath; - } - - @Override - protected void update(float percent) { - if (soundFilePath != null && !midiSoundManager.getStartedSoundfilePaths().isEmpty()) { - SoundFilePathWithSprite spriteSoundFilePath = new SoundFilePathWithSprite(soundFilePath, scope.getSprite()); - Set recentlyStarted = midiSoundManager.getStartedSoundfilePaths(); - if (recentlyStarted.contains(spriteSoundFilePath) && !midiSoundManager.isSoundInSpritePlaying(scope.getSprite(), soundFilePath)) { - recentlyStarted.remove(spriteSoundFilePath); - finish(); - soundStopped = true; - return; - } - } - if (soundFilePath != null && !soundManager.getRecentlyStoppedSoundfilePaths().isEmpty()) { - SoundFilePathWithSprite spriteSoundFilePath = - new SoundFilePathWithSprite(soundFilePath, scope.getSprite()); - Set recentlyStopped = - soundManager.getRecentlyStoppedSoundfilePaths(); - if (recentlyStopped.contains(spriteSoundFilePath)) { - recentlyStopped.remove(spriteSoundFilePath); - finish(); - soundStopped = true; - } - } - } - - @Override - protected void end() { - for (MediaPlayerWithSoundDetails mediaPlayer : soundManager.getMediaPlayers()) { - if (mediaPlayer.isPlaying() && mediaPlayer.getStartedBySprite() == scope.getSprite() && mediaPlayer.getPathToSoundFile().equals(soundFilePath) && !soundStopped) { - restart(); - setTime(mediaPlayer.getCurrentPosition()); - } - } - for (MidiPlayer midiPlayer : midiSoundManager.getMidiPlayers()) { - if (midiPlayer.isPlaying() && midiPlayer.getStartedBySprite() == scope.getSprite() && midiPlayer.getPathToSoundFile().equals(soundFilePath) && !soundStopped) { - restart(); - setTime(midiPlayer.getCurrentPosition()); - } - } - } - - @VisibleForTesting - public void setSoundManager(SoundManager soundManager) { - this.soundManager = soundManager; - } - - @VisibleForTesting - public void setMidiSoundManager(MidiSoundManager midiSoundManager) { - this.midiSoundManager = midiSoundManager; - } -} diff --git a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt new file mode 100644 index 00000000000..4c91209a28d --- /dev/null +++ b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt @@ -0,0 +1,102 @@ +/* + * Catroid: An on-device visual programming system for Android devices + * Copyright (C) 2010-2026 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * An additional term exception under section 7 of the GNU Affero + * General Public License, version 3, is available at + * http://developer.catrobat.org/license_additional_term + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.catrobat.catroid.content.actions + +import androidx.annotation.VisibleForTesting +import org.catrobat.catroid.content.SoundFilePathWithSprite +import org.catrobat.catroid.io.SoundManager +import org.catrobat.catroid.pocketmusic.mididriver.MidiSoundManager + +class WaitForSoundAction : WaitAction() { + + var soundFilePath: String? = null + + @VisibleForTesting + var soundManager: SoundManager = SoundManager.getInstance() + + @VisibleForTesting + var midiSoundManager: MidiSoundManager = MidiSoundManager.getInstance() + + private var soundStopped = false + + override fun update(percent: Float) { + val path = soundFilePath ?: return + val sprite = scope.sprite + + val startedPaths = midiSoundManager.startedSoundfilePaths + if (startedPaths.isNotEmpty()) { + val spriteSoundFilePath = SoundFilePathWithSprite(path, sprite) + if (spriteSoundFilePath in startedPaths && + !midiSoundManager.isSoundInSpritePlaying(sprite, path) + ) { + startedPaths.remove(spriteSoundFilePath) + finish() + soundStopped = true + return + } + } + + val stoppedPaths = soundManager.recentlyStoppedSoundfilePaths + if (stoppedPaths.isNotEmpty()) { + val spriteSoundFilePath = SoundFilePathWithSprite(path, sprite) + if (spriteSoundFilePath in stoppedPaths) { + stoppedPaths.remove(spriteSoundFilePath) + finish() + soundStopped = true + } + } + } + + override fun end() { + val path = soundFilePath ?: return + val sprite = scope.sprite + + for (mediaPlayer in soundManager.mediaPlayers) { + if (mediaPlayer.isPlaying && + mediaPlayer.startedBySprite === sprite && + mediaPlayer.pathToSoundFile == path && + !soundStopped + ) { + restart() + setTime(mediaPlayer.currentPosition) + } + } + + for (midiPlayer in midiSoundManager.midiPlayers) { + if (midiPlayer.isPlaying && + midiPlayer.startedBySprite === sprite && + midiPlayer.pathToSoundFile == path && + !soundStopped + ) { + restart() + setTime(midiPlayer.currentPosition) + } + } + } + + companion object { + @JvmField + val TAG: String = WaitForSoundAction::class.java.simpleName + } +} From 3e79a6fe42c79fb292b096ada73f0c8cd49b51f0 Mon Sep 17 00:00:00 2001 From: harshsomankar123-tech Date: Fri, 10 Apr 2026 15:43:28 +0530 Subject: [PATCH 2/4] Simplify complex conditions in end() for Detekt --- .../catrobat/catroid/content/actions/WaitForSoundAction.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt index 4c91209a28d..6b57b5ceccd 100644 --- a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt +++ b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt @@ -69,14 +69,14 @@ class WaitForSoundAction : WaitAction() { } override fun end() { + if (soundStopped) return val path = soundFilePath ?: return val sprite = scope.sprite for (mediaPlayer in soundManager.mediaPlayers) { if (mediaPlayer.isPlaying && mediaPlayer.startedBySprite === sprite && - mediaPlayer.pathToSoundFile == path && - !soundStopped + mediaPlayer.pathToSoundFile == path ) { restart() setTime(mediaPlayer.currentPosition) @@ -86,8 +86,7 @@ class WaitForSoundAction : WaitAction() { for (midiPlayer in midiSoundManager.midiPlayers) { if (midiPlayer.isPlaying && midiPlayer.startedBySprite === sprite && - midiPlayer.pathToSoundFile == path && - !soundStopped + midiPlayer.pathToSoundFile == path ) { restart() setTime(midiPlayer.currentPosition) From 31b5db2a91c50d1751668cd05d45098e7f5b36b6 Mon Sep 17 00:00:00 2001 From: harshsomankar123-tech Date: Fri, 10 Apr 2026 15:58:28 +0530 Subject: [PATCH 3/4] Fix detekt complexity and Float type mismatch errors --- .../catrobat/catroid/content/actions/WaitForSoundAction.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt index 6b57b5ceccd..ad5f38ee7d4 100644 --- a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt +++ b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt @@ -79,7 +79,7 @@ class WaitForSoundAction : WaitAction() { mediaPlayer.pathToSoundFile == path ) { restart() - setTime(mediaPlayer.currentPosition) + setTime(mediaPlayer.currentPosition.toFloat()) } } @@ -89,7 +89,7 @@ class WaitForSoundAction : WaitAction() { midiPlayer.pathToSoundFile == path ) { restart() - setTime(midiPlayer.currentPosition) + setTime(midiPlayer.currentPosition.toFloat()) } } } From 89e0bd31f99e0dee461f1c35d5ca7dc283a0826e Mon Sep 17 00:00:00 2001 From: harshsomankar123-tech Date: Fri, 17 Apr 2026 01:33:09 +0530 Subject: [PATCH 4/4] CATROID-1554: Fix unit conversion and reset soundStopped flag in WaitForSoundAction --- .../catroid/content/actions/WaitForSoundAction.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt index ad5f38ee7d4..0b7d2f165e3 100644 --- a/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt +++ b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt @@ -40,6 +40,11 @@ class WaitForSoundAction : WaitAction() { private var soundStopped = false + override fun restart() { + soundStopped = false + super.restart() + } + override fun update(percent: Float) { val path = soundFilePath ?: return val sprite = scope.sprite @@ -79,7 +84,7 @@ class WaitForSoundAction : WaitAction() { mediaPlayer.pathToSoundFile == path ) { restart() - setTime(mediaPlayer.currentPosition.toFloat()) + setTime(mediaPlayer.currentPosition.toFloat() / MILLISECONDS_IN_SECOND) } } @@ -89,7 +94,7 @@ class WaitForSoundAction : WaitAction() { midiPlayer.pathToSoundFile == path ) { restart() - setTime(midiPlayer.currentPosition.toFloat()) + setTime(midiPlayer.currentPosition.toFloat() / MILLISECONDS_IN_SECOND) } } } @@ -97,5 +102,7 @@ class WaitForSoundAction : WaitAction() { companion object { @JvmField val TAG: String = WaitForSoundAction::class.java.simpleName + + private const val MILLISECONDS_IN_SECOND = 1000f } }