Skip to content

Commit 1a3c63a

Browse files
committed
Fix ConcurrentModificationException updating sound volumes
Signed-off-by: Lilly Rose Berner <lilly@lostluma.net>
1 parent 17c7834 commit 1a3c63a

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

platforms/common/src/main/java/dynamic_fps/impl/mixin/SoundEngineMixin.java

+23-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package dynamic_fps.impl.mixin;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
35
import java.util.Map;
6+
import java.util.Set;
47

58
import dynamic_fps.impl.feature.volume.SmoothVolumeHandler;
9+
import dynamic_fps.impl.util.Logging;
610
import net.minecraft.client.Minecraft;
711
import org.jetbrains.annotations.Nullable;
812
import org.spongepowered.asm.mixin.Final;
@@ -66,9 +70,24 @@ private float calculateVolume(SoundInstance instance) {
6670
// Also fixes this compat bug: https://github.com/juliand665/Dynamic-FPS/issues/55
6771
boolean isMusic = source.equals(SoundSource.MUSIC) || source.equals(SoundSource.RECORDS);
6872

69-
this.instanceToChannel.forEach((instance, handle) -> {
70-
if (!instance.getSource().equals(source)) {
71-
return;
73+
// Create a copy of all currently active sounds, as iterating over this collection
74+
// Can throw if a sound instance stops playing while we are updating sound volumes
75+
List<SoundInstance> sounds;
76+
77+
try {
78+
sounds = new ArrayList<>(this.instanceToChannel.keySet());
79+
} catch (Throwable e) {
80+
Logging.getLogger().error("Unable to update source volume!", e);
81+
return;
82+
}
83+
84+
// Using our copy should now be safe as long as we check the channel handle exists
85+
while (!sounds.isEmpty()) {
86+
SoundInstance instance = sounds.removeFirst();
87+
ChannelAccess.ChannelHandle handle = this.instanceToChannel.get(instance);
88+
89+
if (handle == null || !instance.getSource().equals(source)) {
90+
continue;
7291
}
7392

7493
float volume = this.calculateVolume(instance);
@@ -93,7 +112,7 @@ private float calculateVolume(SoundInstance instance) {
93112
channel.setVolume(volume);
94113
}
95114
});
96-
});
115+
}
97116
}
98117

99118
/**

0 commit comments

Comments
 (0)