followup on fixed AudioClip deadlock

This commit is contained in:
NikolayHD
2019-08-30 00:51:47 +03:00
parent 154a91a418
commit f62f2832dd

View File

@@ -37,6 +37,7 @@ import java.util.function.Supplier;
public class AudioClip implements IAudioClip { public class AudioClip implements IAudioClip {
private Clip clip; private Clip clip;
private boolean started; private boolean started;
private boolean looping;
public static boolean fileExists(String fileName) { public static boolean fileExists(String fileName) {
File fSound = new File(ForgeConstants.SOUND_DIR, fileName); File fSound = new File(ForgeConstants.SOUND_DIR, fileName);
@@ -76,7 +77,16 @@ public class AudioClip implements IAudioClip {
return; return;
} }
synchronized (this) { synchronized (this) {
if (clip.isRunning()) {
// introduce small delay to make a batch sounds more granular,
// e.g. when you auto-tap 4 lands the 4 tap sounds should
// not become completely merged
waitSoundSystemDelay();
}
clip.setMicrosecondPosition(0); clip.setMicrosecondPosition(0);
if (!this.looping && clip.isRunning()) {
return;
}
this.started = false; this.started = false;
clip.start(); clip.start();
wait(() -> this.started); wait(() -> this.started);
@@ -90,9 +100,13 @@ public class AudioClip implements IAudioClip {
} }
synchronized (this) { synchronized (this) {
clip.setMicrosecondPosition(0); clip.setMicrosecondPosition(0);
if (this.looping && clip.isRunning()) {
return;
}
this.started = false; this.started = false;
clip.loop(Clip.LOOP_CONTINUOUSLY); clip.loop(Clip.LOOP_CONTINUOUSLY);
wait(() -> this.started); wait(() -> this.started);
this.looping = true;
} }
} }
@@ -103,6 +117,7 @@ public class AudioClip implements IAudioClip {
} }
synchronized (this) { synchronized (this) {
clip.stop(); clip.stop();
this.looping = false;
} }
} }
@@ -117,18 +132,22 @@ public class AudioClip implements IAudioClip {
private void wait(Supplier<Boolean> completed) { private void wait(Supplier<Boolean> completed) {
final int attempts = 5; final int attempts = 5;
for (int i = 0; i < attempts; i++) { for (int i = 0; i < attempts; i++) {
if (completed.get()) { if (completed.get() || !waitSoundSystemDelay()) {
break;
}
try {
Thread.sleep(SoundSystem.DELAY);
} catch (InterruptedException ex) {
ex.printStackTrace();
break; break;
} }
} }
} }
private boolean waitSoundSystemDelay() {
try {
Thread.sleep(SoundSystem.DELAY);
return true;
} catch (InterruptedException ex) {
ex.printStackTrace();
return false;
}
}
private void lineStatusChanged(LineEvent line) { private void lineStatusChanged(LineEvent line) {
LineEvent.Type status = line.getType(); LineEvent.Type status = line.getType();
this.started |= status == LineEvent.Type.START; this.started |= status == LineEvent.Type.START;