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..0b7d2f165e3 --- /dev/null +++ b/catroid/src/main/java/org/catrobat/catroid/content/actions/WaitForSoundAction.kt @@ -0,0 +1,108 @@ +/* + * 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 restart() { + soundStopped = false + super.restart() + } + + 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() { + 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 + ) { + restart() + setTime(mediaPlayer.currentPosition.toFloat() / MILLISECONDS_IN_SECOND) + } + } + + for (midiPlayer in midiSoundManager.midiPlayers) { + if (midiPlayer.isPlaying && + midiPlayer.startedBySprite === sprite && + midiPlayer.pathToSoundFile == path + ) { + restart() + setTime(midiPlayer.currentPosition.toFloat() / MILLISECONDS_IN_SECOND) + } + } + } + + companion object { + @JvmField + val TAG: String = WaitForSoundAction::class.java.simpleName + + private const val MILLISECONDS_IN_SECOND = 1000f + } +}