120 lines
4.1 KiB
Java
120 lines
4.1 KiB
Java
package net.minecraft.client.sounds;
|
|
|
|
import com.google.common.collect.Maps;
|
|
import com.mojang.blaze3d.audio.SoundBuffer;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.nio.ByteBuffer;
|
|
import java.util.Collection;
|
|
import java.util.Map;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.concurrent.CompletionException;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.Util;
|
|
import net.minecraft.client.resources.sounds.Sound;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.server.packs.resources.ResourceProvider;
|
|
|
|
/**
|
|
* The {@linkplain SoundBufferLibrary} class provides a cache containing instances of {@linkplain SoundBuffer} and {@linkplain AudioStream} for use in Minecraft sound handling.
|
|
*/
|
|
@Environment(EnvType.CLIENT)
|
|
public class SoundBufferLibrary {
|
|
/**
|
|
* The {@linkplain ResourceProvider} used for loading sound resources.
|
|
*/
|
|
private final ResourceProvider resourceManager;
|
|
private final Map<ResourceLocation, CompletableFuture<SoundBuffer>> cache = Maps.<ResourceLocation, CompletableFuture<SoundBuffer>>newHashMap();
|
|
|
|
public SoundBufferLibrary(ResourceProvider resourceManager) {
|
|
this.resourceManager = resourceManager;
|
|
}
|
|
|
|
/**
|
|
* {@return Returns a {@linkplain CompletableFuture} containing the complete {@linkplain SoundBuffer}. The {@linkplain SoundBuffer} is loaded asynchronously and cached.}
|
|
*
|
|
* @param soundID the {@linkplain ResourceLocation} of the sound
|
|
*/
|
|
public CompletableFuture<SoundBuffer> getCompleteBuffer(ResourceLocation soundID) {
|
|
return (CompletableFuture<SoundBuffer>)this.cache.computeIfAbsent(soundID, resourceLocation -> CompletableFuture.supplyAsync(() -> {
|
|
try {
|
|
InputStream inputStream = this.resourceManager.open(resourceLocation);
|
|
|
|
SoundBuffer var5;
|
|
try {
|
|
FiniteAudioStream finiteAudioStream = new JOrbisAudioStream(inputStream);
|
|
|
|
try {
|
|
ByteBuffer byteBuffer = finiteAudioStream.readAll();
|
|
var5 = new SoundBuffer(byteBuffer, finiteAudioStream.getFormat());
|
|
} catch (Throwable var8) {
|
|
try {
|
|
finiteAudioStream.close();
|
|
} catch (Throwable var7) {
|
|
var8.addSuppressed(var7);
|
|
}
|
|
|
|
throw var8;
|
|
}
|
|
|
|
finiteAudioStream.close();
|
|
} catch (Throwable var9) {
|
|
if (inputStream != null) {
|
|
try {
|
|
inputStream.close();
|
|
} catch (Throwable var6) {
|
|
var9.addSuppressed(var6);
|
|
}
|
|
}
|
|
|
|
throw var9;
|
|
}
|
|
|
|
if (inputStream != null) {
|
|
inputStream.close();
|
|
}
|
|
|
|
return var5;
|
|
} catch (IOException var10) {
|
|
throw new CompletionException(var10);
|
|
}
|
|
}, Util.nonCriticalIoPool()));
|
|
}
|
|
|
|
/**
|
|
* {@return Returns a {@linkplain CompletableFuture} containing the {@linkplain AudioStream}. The {@linkplain AudioStream} is loaded asynchronously.}
|
|
*
|
|
* @param resourceLocation the {@linkplain ResourceLocation} of the sound
|
|
* @param isWrapper whether the {@linkplain AudioStream} should be a {@linkplain LoopingAudioStream}
|
|
*/
|
|
public CompletableFuture<AudioStream> getStream(ResourceLocation resourceLocation, boolean isWrapper) {
|
|
return CompletableFuture.supplyAsync(() -> {
|
|
try {
|
|
InputStream inputStream = this.resourceManager.open(resourceLocation);
|
|
return (AudioStream)(isWrapper ? new LoopingAudioStream(JOrbisAudioStream::new, inputStream) : new JOrbisAudioStream(inputStream));
|
|
} catch (IOException var4) {
|
|
throw new CompletionException(var4);
|
|
}
|
|
}, Util.nonCriticalIoPool());
|
|
}
|
|
|
|
/**
|
|
* Clears the cache of all {@linkplain SoundBuffer} instances.
|
|
*/
|
|
public void clear() {
|
|
this.cache.values().forEach(completableFuture -> completableFuture.thenAccept(SoundBuffer::discardAlBuffer));
|
|
this.cache.clear();
|
|
}
|
|
|
|
/**
|
|
* Preloads the {@linkplain SoundBuffer} objects for the specified collection of sounds.
|
|
* <p>
|
|
* @return a {@linkplain CompletableFuture} representing the completion of the preload operation
|
|
*
|
|
* @param sounds the collection of sounds to preload
|
|
*/
|
|
public CompletableFuture<?> preload(Collection<Sound> sounds) {
|
|
return CompletableFuture.allOf((CompletableFuture[])sounds.stream().map(sound -> this.getCompleteBuffer(sound.getPath())).toArray(CompletableFuture[]::new));
|
|
}
|
|
}
|